1 | 'use strict';
|
2 |
|
3 | const assert = require('assert');
|
4 | const stream = require('stream');
|
5 |
|
6 | const fontoxmlDevelopmentTools = require('../');
|
7 |
|
8 | const AssertableWritableStream = fontoxmlDevelopmentTools.AssertableWritableStream;
|
9 |
|
10 | let testOutput;
|
11 |
|
12 | describe('AssertableWritableStream', () => {
|
13 | beforeEach(() => {
|
14 | testOutput = new AssertableWritableStream();
|
15 | });
|
16 |
|
17 | it('extends stream.Writable', () => {
|
18 | assert.ok(testOutput instanceof stream.Writable);
|
19 | assert.ok(testOutput._write);
|
20 | });
|
21 |
|
22 | it('can write to stream', () => {
|
23 | assert.ok(typeof testOutput.write === 'function');
|
24 | assert.ok(typeof testOutput._write === 'function');
|
25 | assert.doesNotThrow(() => {
|
26 | testOutput.write('test output');
|
27 | });
|
28 | });
|
29 |
|
30 | it('can capture output', () => {
|
31 | testOutput.write('test output');
|
32 | testOutput.assert('test output');
|
33 | });
|
34 |
|
35 | it('can give a copy of all written output', () => {
|
36 | testOutput.write('test output 1');
|
37 | testOutput.write('test output 2');
|
38 | const output = testOutput.getOutput();
|
39 | assert.ok(output);
|
40 | assert.strictEqual(output.length, 2);
|
41 | assert.deepEqual(output, [
|
42 | 'test output 1',
|
43 | 'test output 2'
|
44 | ]);
|
45 | });
|
46 |
|
47 | it('can reset the output', () => {
|
48 | testOutput.write('test output');
|
49 | testOutput.assert('test output');
|
50 | testOutput.resetOutput();
|
51 | const output = testOutput.getOutput();
|
52 | assert.ok(output);
|
53 | assert.strictEqual(output.length, 0);
|
54 | });
|
55 |
|
56 | it('can write multiple values when in cork mode', () => {
|
57 | testOutput.cork();
|
58 | testOutput.write('test output 1');
|
59 | testOutput.write('test output 2');
|
60 | let output = testOutput.getOutput();
|
61 | assert.ok(output);
|
62 | assert.strictEqual(output.length, 0);
|
63 | testOutput.uncork();
|
64 | output = testOutput.getOutput();
|
65 | assert.ok(output);
|
66 | assert.strictEqual(output.length, 2);
|
67 | assert.deepEqual(output, [
|
68 | 'test output 1',
|
69 | 'test output 2'
|
70 | ]);
|
71 | });
|
72 |
|
73 | it('can provide raw output', () => {
|
74 | testOutput = new AssertableWritableStream({ decodeStrings: true });
|
75 | testOutput.write('test output 1');
|
76 | testOutput.write('test output 2', 'utf8');
|
77 | testOutput.write('test output 3', 'ascii');
|
78 | testOutput.write(new Buffer('test output 4', 'utf8'));
|
79 |
|
80 | const rawOutput = testOutput.getRawOutput();
|
81 | assert.ok(rawOutput);
|
82 | assert.strictEqual(rawOutput.length, 4);
|
83 | assert.deepEqual(rawOutput, [
|
84 | {
|
85 | chunk: new Buffer('test output 1', 'utf8'),
|
86 | encoding: 'buffer'
|
87 | },
|
88 | {
|
89 | chunk: new Buffer('test output 2', 'utf8'),
|
90 | encoding: 'buffer'
|
91 | },
|
92 | {
|
93 | chunk: new Buffer('test output 3', 'ascii'),
|
94 | encoding: 'buffer'
|
95 | },
|
96 | {
|
97 | chunk: new Buffer('test output 4', 'utf8'),
|
98 | encoding: 'buffer'
|
99 | }
|
100 | ]);
|
101 | });
|
102 |
|
103 | it('can re-enable decodeStrings and get raw output', () => {
|
104 | testOutput.write('test output 1');
|
105 | testOutput.write('test output 2', 'utf8');
|
106 | testOutput.write('test output 3', 'ascii');
|
107 | testOutput.write(new Buffer('test output 4', 'utf8'));
|
108 |
|
109 | const rawOutput = testOutput.getRawOutput();
|
110 | assert.ok(rawOutput);
|
111 | assert.strictEqual(rawOutput.length, 4);
|
112 | assert.deepEqual(rawOutput, [
|
113 | {
|
114 | chunk: 'test output 1',
|
115 | encoding: 'utf8'
|
116 | },
|
117 | {
|
118 | chunk: 'test output 2',
|
119 | encoding: 'utf8'
|
120 | },
|
121 | {
|
122 | chunk: 'test output 3',
|
123 | encoding: 'ascii'
|
124 | },
|
125 | {
|
126 | chunk: new Buffer('test output 4', 'utf8'),
|
127 | encoding: 'buffer'
|
128 | }
|
129 | ]);
|
130 |
|
131 | const output = testOutput.getOutput();
|
132 | assert.ok(output);
|
133 | assert.strictEqual(output.length, 4);
|
134 | assert.deepEqual(output, [
|
135 | 'test output 1',
|
136 | 'test output 2',
|
137 | 'test output 3',
|
138 | 'test output 4'
|
139 | ]);
|
140 | });
|
141 |
|
142 | it('supports object mode', () => {
|
143 | testOutput = new AssertableWritableStream({ objectMode: true });
|
144 |
|
145 | function TestObject (text) {
|
146 | this.text = text;
|
147 | }
|
148 |
|
149 | TestObject.prototype.toString = function () {
|
150 | return this.text;
|
151 | };
|
152 |
|
153 | const testObject = new TestObject('test output 4');
|
154 |
|
155 | testOutput.write('test output 1');
|
156 | testOutput.write('test output 2', 'utf8');
|
157 | testOutput.write('test output 3', 'ascii');
|
158 | testOutput.write(testObject, 'object');
|
159 | testOutput.write({ test: 'output 5' });
|
160 |
|
161 | const rawOutput = testOutput.getRawOutput();
|
162 | assert.ok(rawOutput);
|
163 | assert.strictEqual(rawOutput.length, 5);
|
164 | assert.deepEqual(rawOutput, [
|
165 | {
|
166 | chunk: 'test output 1',
|
167 | encoding: 'utf8'
|
168 | },
|
169 | {
|
170 | chunk: 'test output 2',
|
171 | encoding: 'utf8'
|
172 | },
|
173 | {
|
174 | chunk: 'test output 3',
|
175 | encoding: 'ascii'
|
176 | },
|
177 | {
|
178 | chunk: testObject,
|
179 | encoding: 'object'
|
180 | },
|
181 | {
|
182 | chunk: { test: 'output 5' },
|
183 | encoding: 'utf8'
|
184 | }
|
185 | ]);
|
186 |
|
187 | const output = testOutput.getOutput();
|
188 | assert.ok(output);
|
189 | assert.strictEqual(output.length, 5);
|
190 | assert.deepEqual(output, [
|
191 | 'test output 1',
|
192 | 'test output 2',
|
193 | 'test output 3',
|
194 | 'test output 4',
|
195 | {}.toString()
|
196 | ]);
|
197 | });
|
198 |
|
199 | describe('.(start|stop)CaptureStream', () => {
|
200 | it('can start capture of a stream', () => {
|
201 | const testStream = new stream.Writable();
|
202 | testOutput.startCaptureStream(testStream);
|
203 | testStream.write('test output 1');
|
204 | testOutput.assert('test output 1');
|
205 | });
|
206 |
|
207 | it('can stop capture of a stream', () => {
|
208 | const testWrite = () => {};
|
209 | const testStream = new stream.Writable({
|
210 | write: testWrite
|
211 | });
|
212 | testOutput.startCaptureStream(testStream);
|
213 | let capturedStreams = testOutput.getCapturedStreams();
|
214 | assert.strictEqual(capturedStreams.length, 1);
|
215 | assert.notStrictEqual(testStream._write, testWrite);
|
216 | testStream.write('test output 1');
|
217 | testOutput.assert('test output 1');
|
218 | testOutput.stopCaptureStream(testStream);
|
219 | capturedStreams = testOutput.getCapturedStreams();
|
220 | assert.strictEqual(capturedStreams.length, 0);
|
221 | assert.strictEqual(testStream._write, testWrite);
|
222 | testStream.write('test output 2');
|
223 | testOutput.assert('test output 1');
|
224 | assert.throws(() => {
|
225 | testOutput.assert('test output 2');
|
226 | }, assert.AssertionError);
|
227 | });
|
228 |
|
229 | it('can capture a corked stream', () => {
|
230 | const testWrite = () => {};
|
231 | const testWritev = () => {};
|
232 | const testStream = new stream.Writable({
|
233 | write: testWrite,
|
234 | writev: testWritev
|
235 | });
|
236 | testOutput.startCaptureStream(testStream);
|
237 | assert.notStrictEqual(testStream._write, testWrite);
|
238 | assert.notStrictEqual(testStream._writev, testWritev);
|
239 | testStream.cork();
|
240 | testStream.write('test output 1');
|
241 | testStream.write('test output 2');
|
242 | let output = testOutput.getOutput();
|
243 | assert.ok(output);
|
244 | assert.strictEqual(output.length, 0);
|
245 | testStream.uncork();
|
246 | output = testOutput.getOutput();
|
247 | assert.ok(output);
|
248 | assert.strictEqual(output.length, 2);
|
249 | assert.deepEqual(output, [
|
250 | 'test output 1',
|
251 | 'test output 2'
|
252 | ]);
|
253 | testOutput.stopCaptureStream(testStream);
|
254 | assert.strictEqual(testStream._write, testWrite);
|
255 | assert.strictEqual(testStream._writev, testWritev);
|
256 | });
|
257 |
|
258 | it('throws an error when the specified stream is not a steam', () => {
|
259 |
|
260 | assert.throws(() => {
|
261 | testOutput.startCaptureStream();
|
262 | }, TypeError);
|
263 | assert.throws(() => {
|
264 | testOutput.startCaptureStream({ _write: () => {} });
|
265 | }, TypeError);
|
266 |
|
267 |
|
268 | assert.throws(() => {
|
269 | testOutput.stopCaptureStream({ _write: () => {} });
|
270 | }, TypeError);
|
271 | });
|
272 |
|
273 | it('returns early when not capturing any stream', () => {
|
274 | const testStream = new stream.Writable();
|
275 | testOutput.stopCaptureStream(testStream);
|
276 | const capturedStreams = testOutput.getCapturedStreams();
|
277 | assert.strictEqual(capturedStreams.length, 0);
|
278 | });
|
279 |
|
280 | it('can capture from multiple streams', () => {
|
281 | const testWrite = () => {};
|
282 | const testStream1 = new stream.Writable({
|
283 | write: testWrite
|
284 | });
|
285 | const testStream2 = new stream.Writable({
|
286 | write: testWrite
|
287 | });
|
288 | testOutput.startCaptureStream(testStream1);
|
289 | testOutput.startCaptureStream(testStream1);
|
290 | testOutput.startCaptureStream(testStream2);
|
291 | let capturedStreams = testOutput.getCapturedStreams();
|
292 | assert.strictEqual(capturedStreams.length, 2);
|
293 | assert.notStrictEqual(testStream1._write, testWrite);
|
294 | assert.notStrictEqual(testStream2._write, testWrite);
|
295 | testStream1.write('test output 1');
|
296 | testStream2.write('test output 1');
|
297 | testOutput.assert('test output 1');
|
298 | testOutput.assert('test output 1', 1);
|
299 | testOutput.stopCaptureStream(testStream1);
|
300 | testOutput.stopCaptureStream(testStream2);
|
301 | capturedStreams = testOutput.getCapturedStreams();
|
302 | assert.strictEqual(capturedStreams.length, 0);
|
303 | assert.strictEqual(testStream1._write, testWrite);
|
304 | assert.strictEqual(testStream2._write, testWrite);
|
305 | testStream1.write('test output 2');
|
306 | testStream2.write('test output 2');
|
307 | assert.throws(() => {
|
308 | testOutput.assert('test output 2');
|
309 | }, assert.AssertionError);
|
310 | });
|
311 |
|
312 | it('can have multiple captures on a stream', () => {
|
313 | const testWrite = () => {};
|
314 | const testStream = new stream.Writable({
|
315 | write: testWrite
|
316 | });
|
317 | const testOutput1 = new AssertableWritableStream();
|
318 | const testOutput2 = new AssertableWritableStream();
|
319 | testOutput1.startCaptureStream(testStream);
|
320 | testOutput2.startCaptureStream(testStream);
|
321 |
|
322 | let capturedStreams1 = testOutput1.getCapturedStreams();
|
323 | let capturedStreams2 = testOutput2.getCapturedStreams();
|
324 | assert.strictEqual(capturedStreams1.length, 1);
|
325 | assert.strictEqual(capturedStreams2.length, 1);
|
326 | assert.notStrictEqual(testStream._write, testWrite);
|
327 | testStream.write('test output 1');
|
328 | testOutput1.assert('test output 1');
|
329 | testOutput2.assert('test output 1');
|
330 |
|
331 | testOutput1.stopCaptureStream(testStream);
|
332 | capturedStreams1 = testOutput1.getCapturedStreams();
|
333 | capturedStreams2 = testOutput2.getCapturedStreams();
|
334 | assert.strictEqual(capturedStreams1.length, 0);
|
335 | assert.strictEqual(capturedStreams2.length, 1);
|
336 | assert.notStrictEqual(testStream._write, testWrite);
|
337 | testStream.write('test output 2');
|
338 | assert.throws(() => {
|
339 | testOutput1.assert('test output 2');
|
340 | }, assert.AssertionError);
|
341 | testOutput2.assert('test output 2');
|
342 |
|
343 | testOutput2.stopCaptureStream(testStream);
|
344 | capturedStreams1 = testOutput1.getCapturedStreams();
|
345 | capturedStreams2 = testOutput2.getCapturedStreams();
|
346 | assert.strictEqual(capturedStreams1.length, 0);
|
347 | assert.strictEqual(capturedStreams2.length, 0);
|
348 | assert.strictEqual(testStream._write, testWrite);
|
349 | testStream.write('test output 3');
|
350 | assert.throws(() => {
|
351 | testOutput1.assert('test output 3');
|
352 | }, assert.AssertionError);
|
353 | assert.throws(() => {
|
354 | testOutput2.assert('test output 3');
|
355 | }, assert.AssertionError);
|
356 | });
|
357 |
|
358 | it('can stop capturing all own captured streams', () => {
|
359 | const testWrite = () => {};
|
360 | const testStream1 = new stream.Writable({
|
361 | write: testWrite
|
362 | });
|
363 | const testStream2 = new stream.Writable({
|
364 | write: testWrite
|
365 | });
|
366 | const testOutput1 = new AssertableWritableStream();
|
367 | const testOutput2 = new AssertableWritableStream();
|
368 | testOutput1.startCaptureStream(testStream1);
|
369 | testOutput1.startCaptureStream(testStream2);
|
370 | testOutput2.startCaptureStream(testStream1);
|
371 | testOutput2.startCaptureStream(testStream2);
|
372 |
|
373 | let capturedStreams1 = testOutput1.getCapturedStreams();
|
374 | let capturedStreams2 = testOutput2.getCapturedStreams();
|
375 | assert.strictEqual(capturedStreams1.length, 2);
|
376 | assert.strictEqual(capturedStreams2.length, 2);
|
377 | assert.notStrictEqual(testStream1._write, testWrite);
|
378 | assert.notStrictEqual(testStream2._write, testWrite);
|
379 | testStream1.write('test output 1');
|
380 | testStream2.write('test output 1');
|
381 | testOutput1.assert('test output 1');
|
382 | testOutput1.assert('test output 1', 1);
|
383 | testOutput2.assert('test output 1');
|
384 | testOutput2.assert('test output 1', 1);
|
385 |
|
386 | testOutput1.stopCaptureStream();
|
387 | capturedStreams1 = testOutput1.getCapturedStreams();
|
388 | capturedStreams2 = testOutput2.getCapturedStreams();
|
389 | assert.strictEqual(capturedStreams1.length, 0);
|
390 | assert.strictEqual(capturedStreams2.length, 2);
|
391 | assert.notStrictEqual(testStream1._write, testWrite);
|
392 | assert.notStrictEqual(testStream2._write, testWrite);
|
393 | testStream1.write('test output 2');
|
394 | testStream2.write('test output 2');
|
395 | assert.throws(() => {
|
396 | testOutput1.assert('test output 2');
|
397 | }, assert.AssertionError);
|
398 | testOutput2.assert('test output 2');
|
399 | testOutput2.assert('test output 2', 2);
|
400 |
|
401 | testOutput2.stopCaptureStream();
|
402 | capturedStreams1 = testOutput1.getCapturedStreams();
|
403 | capturedStreams2 = testOutput2.getCapturedStreams();
|
404 | assert.strictEqual(capturedStreams1.length, 0);
|
405 | assert.strictEqual(capturedStreams2.length, 0);
|
406 | assert.strictEqual(testStream1._write, testWrite);
|
407 | assert.strictEqual(testStream2._write, testWrite);
|
408 | testStream1.write('test output 3');
|
409 | testStream2.write('test output 3');
|
410 | assert.throws(() => {
|
411 | testOutput1.assert('test output 3');
|
412 | }, assert.AssertionError);
|
413 | assert.throws(() => {
|
414 | testOutput2.assert('test output 3');
|
415 | }, assert.AssertionError);
|
416 | });
|
417 |
|
418 | it('handles callback correctly', function (done) {
|
419 | this.slow(500);
|
420 | const testWriteOutput = [];
|
421 | const testWrite = (streamIndex, chunk, _encoding, callback) => {
|
422 | testWriteOutput.push({
|
423 | streamIndex,
|
424 | chunk
|
425 | });
|
426 |
|
427 | if (testWriteOutput.length) {
|
428 | setTimeout(callback, 100);
|
429 | }
|
430 | else {
|
431 | callback();
|
432 | }
|
433 | };
|
434 | const testStream = new stream.Writable();
|
435 | const testOutput1 = new AssertableWritableStream();
|
436 | const testOutput2 = new AssertableWritableStream();
|
437 | testOutput1._write = testWrite.bind(testOutput1, 1);
|
438 | testOutput2._write = testWrite.bind(testOutput2, 2);
|
439 | testOutput1.startCaptureStream(testStream);
|
440 | testOutput2.startCaptureStream(testStream);
|
441 | testStream.write('test output 1', 'utf8', () => {
|
442 | assert.deepEqual(testWriteOutput, [
|
443 | {
|
444 | streamIndex: 1,
|
445 | chunk: new Buffer('test output 1', 'utf8')
|
446 | },
|
447 | {
|
448 | streamIndex: 2,
|
449 | chunk: new Buffer('test output 1', 'utf8')
|
450 | }
|
451 | ]);
|
452 | done();
|
453 | });
|
454 | });
|
455 |
|
456 | it('handles callback errors correctly', function (done) {
|
457 | this.slow(500);
|
458 | const testWriteOutput = [];
|
459 | const testWrite = (streamIndex, chunk, _encoding, callback) => {
|
460 |
|
461 | if (streamIndex === 2) {
|
462 | setTimeout(callback, 100);
|
463 | }
|
464 | else {
|
465 | testWriteOutput.push({
|
466 | streamIndex,
|
467 | chunk
|
468 | });
|
469 | callback(new Error('Write error'));
|
470 | }
|
471 | };
|
472 | const testStream = new stream.Writable();
|
473 | const testOutput1 = new AssertableWritableStream();
|
474 | const testOutput2 = new AssertableWritableStream();
|
475 | testOutput1._write = testWrite.bind(testOutput1, 1);
|
476 | testOutput2._write = testWrite.bind(testOutput2, 2);
|
477 | testOutput1.startCaptureStream(testStream);
|
478 | testOutput2.startCaptureStream(testStream);
|
479 | assert.throws(() => {
|
480 | testStream.write('test output 1', 'utf8', (error) => {
|
481 | assert(error);
|
482 | assert.deepEqual(testWriteOutput, [
|
483 | {
|
484 | streamIndex: 1,
|
485 | chunk: new Buffer('test output 1', 'utf8')
|
486 | }
|
487 | ]);
|
488 | done();
|
489 | });
|
490 | }, /Write error/);
|
491 | });
|
492 |
|
493 | it('throws error when callbacks are called multiple times', function () {
|
494 | const testWriteOutput = [];
|
495 | const testWrite = (streamIndex, chunk, _encoding, callback) => {
|
496 | testWriteOutput.push({
|
497 | streamIndex,
|
498 | chunk
|
499 | });
|
500 |
|
501 | callback();
|
502 | callback();
|
503 | };
|
504 | const testStream = new stream.Writable();
|
505 | const testOutput1 = new AssertableWritableStream();
|
506 | const testOutput2 = new AssertableWritableStream();
|
507 | testOutput1._write = testWrite.bind(testOutput1, 1);
|
508 | testOutput2._write = testWrite.bind(testOutput2, 2);
|
509 | testOutput1.startCaptureStream(testStream);
|
510 | testOutput2.startCaptureStream(testStream);
|
511 | assert.throws(() => {
|
512 | testStream.write('test output 1', 'utf8', () => {
|
513 |
|
514 | });
|
515 | }, /called multiple times/);
|
516 | });
|
517 |
|
518 | it.skip('handles callback correctly in cork mode', function (done) {
|
519 | this.slow(500);
|
520 | const testWritevOutput = [];
|
521 | const testWritev = (streamIndex, chunks, callback) => {
|
522 | testWritevOutput.push({
|
523 | streamIndex,
|
524 | chunks
|
525 | });
|
526 |
|
527 | if (testWritevOutput.length) {
|
528 | setTimeout(callback, 100);
|
529 | }
|
530 | else {
|
531 | callback();
|
532 | }
|
533 | };
|
534 | const testStream = new stream.Writable({
|
535 | writev: function (chunks, callback) {
|
536 | function writeOne () {
|
537 | const chunk = chunks.shift();
|
538 | if (!chunk) {
|
539 | callback();
|
540 | return;
|
541 | }
|
542 | testStream._write(chunk, writeOne);
|
543 | }
|
544 |
|
545 | writeOne(testStream);
|
546 | }
|
547 | });
|
548 | const testOutput1 = new AssertableWritableStream();
|
549 | const testOutput2 = new AssertableWritableStream();
|
550 | testOutput1._writev = testWritev.bind(undefined, 1);
|
551 | testOutput2._writev = testWritev.bind(undefined, 2);
|
552 | testOutput1.startCaptureStream(testStream);
|
553 | testOutput2.startCaptureStream(testStream);
|
554 | testOutput1.cork();
|
555 | testOutput2.cork();
|
556 | testStream.write('test output 1', 'utf8', () => {
|
557 | assert.deepEqual(testWritevOutput, []);
|
558 | });
|
559 | testOutput1.uncork();
|
560 | testOutput2.uncork();
|
561 |
|
562 | testOutput2.end(() => {
|
563 | assert.deepEqual(testWritevOutput, [
|
564 | {
|
565 | streamIndex: 1,
|
566 | chunks: [
|
567 | new Buffer('test output 1', 'utf8')
|
568 | ]
|
569 | },
|
570 | {
|
571 | streamIndex: 2,
|
572 | chunks: [
|
573 | new Buffer('test output 1', 'utf8')
|
574 | ]
|
575 | }
|
576 | ]);
|
577 | done();
|
578 | });
|
579 | });
|
580 | });
|
581 |
|
582 | describe('.findOutputIndex()', () => {
|
583 | it('can find the index of a value', () => {
|
584 | testOutput.write('test output');
|
585 | const index = testOutput.findOutputIndex('test output');
|
586 | assert.strictEqual(index, 0);
|
587 | });
|
588 |
|
589 | it('can find the index of a partial value', () => {
|
590 | testOutput.write('test partial output');
|
591 | const index = testOutput.findOutputIndex('partial');
|
592 | assert.strictEqual(index, 0);
|
593 | });
|
594 |
|
595 | it('can find the index of a RegExp value', () => {
|
596 | testOutput.write('test partial output');
|
597 | testOutput.write('test RegExp output');
|
598 | const index = testOutput.findOutputIndex(/test (?!partial).+ output/);
|
599 | assert.strictEqual(index, 1);
|
600 | });
|
601 |
|
602 | it('returns -1 when the value is not found', () => {
|
603 | testOutput.write('test output');
|
604 | const index = testOutput.findOutputIndex('non existing value');
|
605 | assert.strictEqual(index, -1);
|
606 | });
|
607 |
|
608 | it('returns -1 early when not output is available', () => {
|
609 | const index = testOutput.findOutputIndex('test output');
|
610 | assert.strictEqual(index, -1);
|
611 | });
|
612 |
|
613 | it('can find the index of a value while starting at a specific index', () => {
|
614 | [
|
615 | 'test output 1a',
|
616 | 'test output 2a',
|
617 | 'test output 3a',
|
618 | 'test output 1b',
|
619 | 'test output 2b',
|
620 | 'test output 3b'
|
621 | ].forEach(testOutput.write.bind(testOutput));
|
622 | const index = testOutput.findOutputIndex('test output 1', 1);
|
623 | assert.strictEqual(index, 2);
|
624 | });
|
625 |
|
626 | it('returns -1 when value is not found while starting at a specific index', () => {
|
627 | [
|
628 | 'test output 1',
|
629 | 'test output 2',
|
630 | 'test output 3'
|
631 | ].forEach(testOutput.write.bind(testOutput));
|
632 | const index = testOutput.findOutputIndex('test output 1', 1);
|
633 | assert.strictEqual(index, -1);
|
634 | });
|
635 |
|
636 | it('throws when startAtIndex is set to a value other then undefined, null or a number', () => {
|
637 | [
|
638 | 'test output 1',
|
639 | 'test output 2',
|
640 | 'test output 3'
|
641 | ].forEach(testOutput.write.bind(testOutput));
|
642 | assert.throws(() => {
|
643 | testOutput.findOutputIndex('test output 2', '1');
|
644 | }, TypeError);
|
645 | });
|
646 | });
|
647 |
|
648 | describe('.outputContains()', () => {
|
649 | it('can check if the output contains a value', () => {
|
650 | testOutput.write('test output');
|
651 | assert.ok(testOutput.outputContains('test output'));
|
652 | });
|
653 |
|
654 | it('can check if the output contains a partial value', () => {
|
655 | testOutput.write('test partial output');
|
656 | assert.ok(testOutput.outputContains('partial'));
|
657 | });
|
658 |
|
659 | it('can check if the output contains a RegExp value', () => {
|
660 | testOutput.write('test partial output');
|
661 | testOutput.write('test RegExp output');
|
662 | assert.ok(testOutput.outputContains(/test (?!partial).+ output/));
|
663 | });
|
664 |
|
665 | it('returns -1 when the output does not contain a value', () => {
|
666 | testOutput.write('test output');
|
667 | assert.ok(!testOutput.outputContains('non existing value'));
|
668 | });
|
669 |
|
670 | it('can check if the output contains a value at the expected index', () => {
|
671 | [
|
672 | 'test output 1',
|
673 | 'test output 2',
|
674 | 'test output 3'
|
675 | ].forEach(testOutput.write.bind(testOutput));
|
676 | assert.ok(testOutput.outputContains('test output 2', 1));
|
677 | });
|
678 |
|
679 | it('returns -1 when the output does not contain a value at the expected index', () => {
|
680 | [
|
681 | 'test output 1',
|
682 | 'test output 2',
|
683 | 'test output 3'
|
684 | ].forEach(testOutput.write.bind(testOutput));
|
685 | assert.ok(!testOutput.outputContains('test output 3', 1));
|
686 | });
|
687 |
|
688 | it('throws when expectedIndex is set to a value other then undefined, null or a number', () => {
|
689 | [
|
690 | 'test output 1',
|
691 | 'test output 2',
|
692 | 'test output 3'
|
693 | ].forEach(testOutput.write.bind(testOutput));
|
694 | assert.throws(() => {
|
695 | testOutput.outputContains('test output 2', '1');
|
696 | }, TypeError);
|
697 | });
|
698 |
|
699 | it('can check if the output contains a value at the expected index while starting at a specific index', () => {
|
700 | [
|
701 | 'test output 1a',
|
702 | 'test output 2a',
|
703 | 'test output 3a',
|
704 | 'test output 1b',
|
705 | 'test output 2b',
|
706 | 'test output 3b'
|
707 | ].forEach(testOutput.write.bind(testOutput));
|
708 | assert.ok(testOutput.outputContains('test output 1', 2, 1));
|
709 | });
|
710 |
|
711 | it('returns -1 when the output does not contain a value at the expected index while starting at a specific index', () => {
|
712 | [
|
713 | 'test output 1',
|
714 | 'test output 2',
|
715 | 'test output 3'
|
716 | ].forEach(testOutput.write.bind(testOutput));
|
717 | assert.ok(!testOutput.outputContains('test output 1', undefined, 1));
|
718 | });
|
719 | });
|
720 |
|
721 | describe('.assert()', () => {
|
722 | it('unit test sanity check: can assert AssertionErrors', () => {
|
723 | assert.ok(assert.AssertionError);
|
724 | assert.doesNotThrow(() => {
|
725 | const _error = new assert.AssertionError({
|
726 | message: 'test assertion error'
|
727 | });
|
728 | });
|
729 | assert.throws(() => {
|
730 | throw new assert.AssertionError({
|
731 | message: 'test assertion error'
|
732 | });
|
733 | }, assert.AssertionError);
|
734 | });
|
735 |
|
736 | it('can assert if the output contains a value', () => {
|
737 | testOutput.write('test output');
|
738 | testOutput.assert('test output');
|
739 | });
|
740 |
|
741 | it('fails assertion if the output does not contain a value', () => {
|
742 | testOutput.write('test output');
|
743 | assert.throws(() => {
|
744 | testOutput.assert('non existing value');
|
745 | }, assert.AssertionError);
|
746 | });
|
747 |
|
748 | it('fails assertion with message if the output does not contain a value', () => {
|
749 | testOutput.write('test output');
|
750 | assert.throws(() => {
|
751 | testOutput.assert('non existing value', undefined, undefined, 'test error message');
|
752 | }, /test error message/);
|
753 | });
|
754 |
|
755 | it('can assert if the output contains a value at the expected index', () => {
|
756 | [
|
757 | 'test output 1',
|
758 | 'test output 2',
|
759 | 'test output 3'
|
760 | ].forEach(testOutput.write.bind(testOutput));
|
761 | testOutput.assert('test output 2', 1);
|
762 | });
|
763 |
|
764 | it('fails assertion if the output does not contain a value at the expected index', () => {
|
765 | [
|
766 | 'test output 1',
|
767 | 'test output 2',
|
768 | 'test output 3'
|
769 | ].forEach(testOutput.write.bind(testOutput));
|
770 | assert.throws(() => {
|
771 | testOutput.assert('test output 3', 1);
|
772 | }, assert.AssertionError);
|
773 | });
|
774 |
|
775 | it('fails assertion if the output does not contain a value at the expected index and the expected index does not exist', () => {
|
776 | [
|
777 | 'test output 1',
|
778 | 'test output 2',
|
779 | 'test output 3'
|
780 | ].forEach(testOutput.write.bind(testOutput));
|
781 | assert.throws(() => {
|
782 | testOutput.assert('test output 3', 42);
|
783 | }, assert.AssertionError);
|
784 | });
|
785 |
|
786 | it('fails assertion with message if the output does not contain a value at the expected index', () => {
|
787 | [
|
788 | 'test output 1',
|
789 | 'test output 2',
|
790 | 'test output 3'
|
791 | ].forEach(testOutput.write.bind(testOutput));
|
792 | assert.throws(() => {
|
793 | testOutput.assert('test output 3', 1, undefined, 'test error message');
|
794 | }, /test error message/);
|
795 | });
|
796 |
|
797 | it('fails assertion with message if the output does not contain a value at the expected index and the expected index does not exist', () => {
|
798 | [
|
799 | 'test output 1',
|
800 | 'test output 2',
|
801 | 'test output 3'
|
802 | ].forEach(testOutput.write.bind(testOutput));
|
803 | assert.throws(() => {
|
804 | testOutput.assert('test output 3', 42, undefined, 'test error message');
|
805 | }, assert.AssertionError);
|
806 | });
|
807 |
|
808 | it('throws when expectedIndex is set to a value other then undefined, null or a number', () => {
|
809 | [
|
810 | 'test output 1',
|
811 | 'test output 2',
|
812 | 'test output 3'
|
813 | ].forEach(testOutput.write.bind(testOutput));
|
814 | assert.throws(() => {
|
815 | testOutput.assert('test output 2', '1');
|
816 | }, TypeError);
|
817 | });
|
818 |
|
819 | it('can assert if the output contains a value at the expected index while starting at a specific index', () => {
|
820 | [
|
821 | 'test output 1a',
|
822 | 'test output 2a',
|
823 | 'test output 3a',
|
824 | 'test output 1b',
|
825 | 'test output 2b',
|
826 | 'test output 3b'
|
827 | ].forEach(testOutput.write.bind(testOutput));
|
828 | testOutput.assert('test output 1', 2, 1, 'unused test error message');
|
829 | });
|
830 |
|
831 | it('can assert if the output contains a value at the expected index while not starting at a specific index', () => {
|
832 | [
|
833 | 'test output 1a',
|
834 | 'test output 2a',
|
835 | 'test output 3a',
|
836 | 'test output 1b',
|
837 | 'test output 2b',
|
838 | 'test output 3b'
|
839 | ].forEach(testOutput.write.bind(testOutput));
|
840 | testOutput.assert('test output 1', 3, undefined, 'unused test error message');
|
841 | });
|
842 |
|
843 | it('fails assertion if the output does not contain a value at the expected index while starting at a specific index', () => {
|
844 | [
|
845 | 'test output 1',
|
846 | 'test output 2',
|
847 | 'test output 3'
|
848 | ].forEach(testOutput.write.bind(testOutput));
|
849 | assert.throws(() => {
|
850 | testOutput.assert('test output 1', undefined, 1);
|
851 | }, assert.AssertionError);
|
852 | });
|
853 |
|
854 | it('fails assertion with message if the output does not contain a value at the expected index while starting at a specific index', () => {
|
855 | [
|
856 | 'test output 1',
|
857 | 'test output 2',
|
858 | 'test output 3'
|
859 | ].forEach(testOutput.write.bind(testOutput));
|
860 | assert.throws(() => {
|
861 | testOutput.assert('test output 1', undefined, 1, 'test error message');
|
862 | }, /test error message/);
|
863 | });
|
864 |
|
865 | it('throws if the value is not a string or RegExp', () => {
|
866 | [
|
867 | 'test output 1',
|
868 | 'test output 2',
|
869 | 'test output 3'
|
870 | ].forEach(testOutput.write.bind(testOutput));
|
871 | assert.throws(() => {
|
872 | testOutput.assert(undefined);
|
873 | }, /Invalid type for value./);
|
874 | });
|
875 | });
|
876 |
|
877 | describe('strip ansi', () => {
|
878 | it('disables strips ansi by default', () => {
|
879 | assert.strictEqual(testOutput.stripAnsi, false);
|
880 | });
|
881 |
|
882 | it('can strip ansi from a string chunk', () => {
|
883 | testOutput = new AssertableWritableStream({ stripAnsi: true });
|
884 | assert.strictEqual(testOutput.stripAnsi, true);
|
885 | testOutput.write('May I have some \u001b[4mcake\u001b[0m please.');
|
886 | testOutput.assert('May I have some cake please.', 0);
|
887 | });
|
888 |
|
889 | it('can enable strip ansi after instantiation', () => {
|
890 | testOutput = new AssertableWritableStream();
|
891 | assert.strictEqual(testOutput.stripAnsi, false);
|
892 | testOutput.stripAnsi = true;
|
893 | testOutput.write('May I have some \u001b[4mcake\u001b[0m please.');
|
894 | testOutput.assert('May I have some cake please.', 0);
|
895 | });
|
896 |
|
897 | it('can disable strip ansi after instantiation', () => {
|
898 | testOutput = new AssertableWritableStream({ stripAnsi: true });
|
899 | assert.strictEqual(testOutput.stripAnsi, true);
|
900 | testOutput.write('May I have some \u001b[4mcake\u001b[0m please.');
|
901 | testOutput.assert('May I have some cake please.', 0);
|
902 | testOutput.stripAnsi = false;
|
903 | testOutput.write('May I have some \u001b[4mcake\u001b[0m please.');
|
904 | testOutput.assert('May I have some \u001b[4mcake\u001b[0m please.', 1);
|
905 | });
|
906 |
|
907 | it('does not strip ansi from a non string chunk', () => {
|
908 | testOutput = new AssertableWritableStream({ stripAnsi: true });
|
909 | assert.strictEqual(testOutput.stripAnsi, true);
|
910 | testOutput.write(new Buffer('May I have some \u001b[4mcake\u001b[0m please.'));
|
911 | testOutput.assert('May I have some \u001b[4mcake\u001b[0m please.', 0);
|
912 | });
|
913 |
|
914 | it('can strip ansi from chunks in cork mode', () => {
|
915 | testOutput = new AssertableWritableStream({ stripAnsi: true });
|
916 | assert.strictEqual(testOutput.stripAnsi, true);
|
917 | testOutput.cork();
|
918 | testOutput.write('May I have some \u001b[4mcake\u001b[0m please.');
|
919 | testOutput.write(new Buffer('May I have some \u001b[4mcake\u001b[0m please.'));
|
920 | testOutput.uncork();
|
921 | testOutput.assert('May I have some cake please.', 0);
|
922 | testOutput.assert('May I have some \u001b[4mcake\u001b[0m please.', 1);
|
923 | });
|
924 | });
|
925 | });
|