import { expect } from 'chai'; import { DuplexBufferStream as Duplex, DEFAULT_INITIAL_SIZE, DEFAULT_FREQUENCY, DEFAULT_INCREMENT_AMOUNT } from './duplex-buffer-stream'; import fixtures from './fixtures'; describe('WritableStreamBuffer with defaults', function() { beforeEach(function() { this.buffer = new Duplex(); }); it('returns false on call to getContents() when empty', function() { expect(this.buffer.getContents()).to.equal(''); }); it('returns false on call to getContentsAsString() when empty', function() { expect(this.buffer.getContentsAsString()).to.equal(''); }); it('backing buffer should be default size', function() { expect(this.buffer.maxSize()).to.equal(DEFAULT_INITIAL_SIZE); }); describe('when writing a simple string', function() { beforeEach(function() { this.buffer.write(fixtures.simpleString); }); it('should have a backing buffer of correct length', function() { expect(this.buffer.size).to.equal(fixtures.simpleString.length); }); it('should have a default max size', function() { expect(this.buffer.maxSize()).to.equal(DEFAULT_INITIAL_SIZE); }); it('contents should be correct', function() { expect(this.buffer.getContentsAsString()).to.equal(fixtures.simpleString); }); it('returns partial contents correctly', function() { var buf = Buffer.concat([ this.buffer.getContents( Math.floor(Buffer.byteLength(fixtures.simpleString) / 2) ), this.buffer.getContents() ]); expect(buf.toString()).to.equal(fixtures.simpleString); }); }); describe('when writing a large binary blob', function() { beforeEach(function() { this.buffer.write(fixtures.largeBinaryData); }); it('should have a backing buffer of correct length', function() { expect(this.buffer.size).to.equal(fixtures.largeBinaryData.length); }); it('should have a larger backing buffer max size', function() { expect(this.buffer.maxSize()).to.equal( DEFAULT_INITIAL_SIZE + DEFAULT_INCREMENT_AMOUNT ); }); it('contents are valid', function() { expect(this.buffer.getContents()).to.deep.equal(fixtures.largeBinaryData); }); }); describe('when writing some simple data to the stream', function() { beforeEach(function() { this.buffer = new Duplex(); this.buffer.write(fixtures.simpleString); }); describe('and retrieving half of it', function() { beforeEach(function() { this.firstStr = this.buffer.getContentsAsString( 'utf8', Math.floor(fixtures.simpleString.length / 2) ); }); it('returns correct data', function() { expect(this.firstStr).to.equal( fixtures.simpleString.substring( 0, Math.floor(fixtures.simpleString.length / 2) ) ); }); it('leaves correct amount of data remaining in buffer', function() { expect(this.buffer.size).to.equal( Math.ceil(fixtures.simpleString.length / 2) ); }); describe('and then retrieving the other half of it', function() { beforeEach(function() { this.secondStr = this.buffer.getContentsAsString( 'utf8', Math.ceil(fixtures.simpleString.length / 2) ); }); it('returns correct data', function() { expect(this.secondStr).to.equal( fixtures.simpleString.substring( Math.floor(fixtures.simpleString.length / 2) ) ); }); it('results in an empty buffer', function() { expect(this.buffer.size).to.equal(0); }); }); }); }); }); describe('WritableStreamBuffer with a different initial size and increment amount', function() { beforeEach(function() { this.buffer = new Duplex(62, 321); }); it('has the correct initial size', function() { expect(this.buffer.maxSize()).to.equal(62); }); describe('after data is written', function() { beforeEach(function() { this.buffer.write(fixtures.binaryData); }); it('has correct initial size + custom increment amount', function() { expect(this.buffer.maxSize()).to.equal(321 + 62); }); }); }); describe('When WritableStreamBuffer is written in two chunks', function() { beforeEach(function() { this.buffer = new Duplex(); this.buffer.write(fixtures.simpleString); this.buffer.write(fixtures.simpleString); }); it('buffer contents are correct', function() { expect(this.buffer.getContentsAsString()).to.equal( fixtures.simpleString + fixtures.simpleString ); }); }); describe('A default ReadableStreamBuffer', function() { beforeEach(function() { this.buffer = new Duplex(); }); it('is a Stream', function() { expect(this.buffer).to.be.an.instanceOf(require('stream').Stream); }); it('is empty by default', function() { expect(this.buffer.size).to.equal(0); }); it('has default backing buffer size', function() { expect(this.buffer.maxSize()).to.equal(DEFAULT_INITIAL_SIZE); }); it('emits end event after data, when stopped', function(done) { var that = this; var str = ''; this.buffer.on('readable', function() { str += (that.buffer.read() || new Buffer(0)).toString('utf8'); }); this.buffer.on('end', function() { expect(str).to.equal(fixtures.unicodeString); done(); }); this.buffer.write(fixtures.unicodeString); this.buffer.stop(); }); // it('pushes new data even if read when empty', function(done) { // var that = this; // var str = ''; // this.buffer.on('readable', function() { // str += (that.buffer.read() || new Buffer(0)).toString('utf8'); // }); // this.buffer.on('end', function() { // expect(str).to.equal(fixtures.unicodeString); // done(); // }); // setTimeout(function() { // that.buffer.write(fixtures.unicodeString, () => { // that.buffer.stop(); // }); // }, DEFAULT_FREQUENCY + 1); // }); describe('when writing binary data', function() { beforeEach(function(done) { var that = this; this.buffer.write(fixtures.binaryData); this.buffer.once('readable', function() { that.data = that.buffer.read(); done(); }); }); it('results in a Buffer', function() { expect(this.data).to.be.an.instanceOf(Buffer); }); it('with the correct data', function() { expect(this.data).to.deep.equal(fixtures.binaryData); }); }); it('supports putting in hex data', function(done) { this.buffer.write('BEEF', 'hex'); var that = this; this.buffer.once('readable', function() { var buf = that.buffer.read(); expect(buf[0]).to.equal(190); expect(buf[1]).to.equal(239); done(); }); }); describe('when writing binary data larger than initial backing buffer size', function() { beforeEach(function() { this.buffer.pause(); this.buffer.write(fixtures.largeBinaryData); }); it('buffer is correct size', function() { expect(this.buffer.size).to.equal(fixtures.largeBinaryData.length); }); it('backing buffer is correct size', function() { expect(this.buffer.maxSize()).to.equal( DEFAULT_INITIAL_SIZE + DEFAULT_INCREMENT_AMOUNT ); }); }); }); describe('A ReadableStreamBuffer using custom chunk size', function() { beforeEach(function(done) { var that = this; this.buffer = new Duplex(undefined, undefined, undefined, 2); this.buffer.once('readable', function() { that.data = that.buffer.read(); done(); }); this.buffer.write(fixtures.binaryData); }); it('yields a Buffer with the correct data', function() { expect(this.data).to.deep.equal(fixtures.binaryData.slice(0, 2)); }); }); describe('A ReadableStreamBuffer using custom frequency', function() { beforeEach(function(done) { var that = this; var startTime = new Date().getTime(); this.buffer = new Duplex(undefined, undefined, 300, undefined); this.buffer.once('readable', function() { that.time = new Date().getTime() - startTime; done(); }); this.buffer.write(fixtures.binaryData); }); it('gave us data after the correct amount of time', function() { // Wtfux: sometimes the timer is coming back a millisecond or two // faster. So we do a 'close-enough' assertion here ;) expect(this.time).to.be.at.least(295); }); });