Arquivos
NodeCopterHack/node_modules/ar-drone/test/unit/video/test-PngEncoder.js
T
2013-08-10 13:15:52 +01:00

229 linhas
6.7 KiB
JavaScript

var common = require('../../common');
var assert = require('assert');
var test = require('utest');
var sinon = require('sinon');
var PngEncoder = require(common.lib + '/video/PngEncoder');
var EventEmitter = require('events').EventEmitter;
test('PngEncoder', {
before: function() {
this.fakeFfmpeg = new EventEmitter();
this.fakeFfmpeg.stdin = new EventEmitter();
this.fakeFfmpeg.stdin.write = sinon.stub();
this.fakeFfmpeg.stdin.end = sinon.stub();
this.fakeFfmpeg.stdout = {pipe: sinon.spy()};
this.fakeFfmpeg.stderr = {pipe: sinon.spy()};
this.fakeSpawn = sinon.stub();
this.fakeSpawn.returns(this.fakeFfmpeg);
this.fakePngSplitter = new EventEmitter();
this.fakeFrameRate = 23;
this.fakeBuffer1 = new Buffer('123');
this.fakeBuffer2 = new Buffer('456');
this.fakeLog = {};
this.encoder = new PngEncoder({
spawn : this.fakeSpawn,
frameRate : this.fakeFrameRate,
pngSplitter : this.fakePngSplitter,
log : this.fakeLog,
});
},
'is a writable stream': function() {
assert.equal(this.encoder.writable, true);
assert.equal(typeof this.encoder.write, 'function');
},
'is a readable stream': function() {
assert.equal(this.encoder.readable, true);
assert.equal(typeof this.encoder.pipe, 'function');
},
'first write() spawns ffmpeg': function() {
this.encoder.write(new Buffer('foo'));
assert.equal(this.fakeSpawn.callCount, 1);
assert.equal(this.fakeSpawn.getCall(0).args[0], 'ffmpeg');
// Another write does not spawn another ffmpeg
this.encoder.write(new Buffer('bar'));
assert.equal(this.fakeSpawn.callCount, 1);
},
'write() spawn ffmpeg with the right arguments': function() {
this.encoder.write(new Buffer('foo'));
var args = this.fakeSpawn.getCall(0).args[1];
// Read from stdin
var input = args.indexOf('-i');
assert.equal(args[input + 1], '-');
// Use the image2pipe format
var format = args.indexOf('-f');
assert.equal(args[format + 1], 'image2pipe');
// Use the png video codec
var vcodec = args.indexOf('-vcodec');
assert.equal(args[vcodec + 1], 'png');
// Sets the right framerate
var frameRate = args.indexOf('-r');
assert.equal(args[frameRate + 1], this.fakeFrameRate);
// Pipe to stdout
assert.equal(args[args.length - 1], '-');
},
'write() pipes ffmpeg.stdout into PngSplitter': function() {
this.encoder.write(new Buffer('foo'));
var stdoutPipe = this.fakeFfmpeg.stdout.pipe;
assert.equal(stdoutPipe.callCount, 1);
assert.strictEqual(stdoutPipe.getCall(0).args[0], this.fakePngSplitter);
},
'proxies all pngSplitter "data"': function() {
var dataSpy = sinon.spy();
this.encoder.on('data', dataSpy);
this.encoder.write(new Buffer('foo'));
this.fakePngSplitter.emit('data', this.fakeBuffer1);
assert.equal(dataSpy.callCount, 1);
assert.strictEqual(dataSpy.getCall(0).args[0], this.fakeBuffer1);
this.fakePngSplitter.emit('data', this.fakeBuffer2);
assert.equal(dataSpy.callCount, 2);
assert.strictEqual(dataSpy.getCall(1).args[0], this.fakeBuffer2);
},
'handles ffmpeg spawn error': function() {
var errorSpy = sinon.spy();
this.encoder.on('error', errorSpy);
this.encoder.write(new Buffer('foo'));
// simulate ffmpeg not spawning correctly
var error = new Error('ENOENT');
error.code = 'ENOENT';
this.fakeFfmpeg.stdin.emit('error', new Error('EPIPE'));
this.fakeFfmpeg.emit('error', error);
assert.equal(errorSpy.callCount, 1);
assert.equal(/ffmpeg.*not found/i.test(errorSpy.getCall(0).args[0]), true);
},
'handles ffmpeg not existing': function() {
var errorSpy = sinon.spy();
this.encoder.on('error', errorSpy);
this.encoder.write(new Buffer('foo'));
// simulate ffmpeg not existing
this.fakeFfmpeg.stdin.emit('error', new Error('EPIPE'));
this.fakeFfmpeg.emit('exit', 127);
assert.equal(errorSpy.callCount, 1);
assert.equal(/ffmpeg.*not found/i.test(errorSpy.getCall(0).args[0]), true);
},
'handles ffmpeg exit code > 0': function() {
var errorSpy = sinon.spy();
this.encoder.on('error', errorSpy);
this.encoder.write(new Buffer('foo'));
// simulate an ffmpeg error
this.fakeFfmpeg.emit('exit', 1);
assert.equal(errorSpy.callCount, 1);
assert.equal(/ffmpeg.*error/i.test(errorSpy.getCall(0).args[0]), true);
},
'handles expected ffmpeg shutdown': function() {
var endSpy = sinon.spy();
this.encoder.on('end', endSpy);
this.encoder.write(new Buffer('foo'));
this.encoder.end();
this.fakeFfmpeg.emit('exit', 0);
assert.equal(endSpy.callCount, 1);
},
'handles unexpected ffmpeg shutdown with exit code 0': function() {
var errorSpy = sinon.spy();
this.encoder.on('error', errorSpy);
this.encoder.write(new Buffer('foo'));
this.fakeFfmpeg.emit('exit', 0);
assert.equal(errorSpy.callCount, 1);
assert.equal(/unexpected.*ffmpeg/i.test(errorSpy.getCall(0).args[0].message), true);
},
'write() passes all data into ffmpeg.stdin': function() {
this.encoder.write(this.fakeBuffer1);
var stdin = this.fakeFfmpeg.stdin;
assert.equal(stdin.write.callCount, 1);
assert.strictEqual(stdin.write.getCall(0).args[0], this.fakeBuffer1);
this.encoder.write(this.fakeBuffer2);
assert.equal(stdin.write.callCount, 2);
assert.strictEqual(stdin.write.getCall(1).args[0], this.fakeBuffer2);
},
'write() handles ffmpeg backpressure': function() {
this.fakeFfmpeg.stdin.write.returns(true);
var r = this.encoder.write(new Buffer('abc'));
assert.equal(r, true);
this.fakeFfmpeg.stdin.write.returns(false);
r = this.encoder.write(new Buffer('abc'));
assert.equal(r, false);
var drainCalled = false;
this.encoder.on('drain', function () {
drainCalled = true;
});
this.fakeFfmpeg.stdin.emit('drain');
assert.ok(drainCalled);
},
'write() pipes ffmpeg stderr to log': function() {
this.encoder.write(new Buffer('abc'));
var stderrPipe = this.fakeFfmpeg.stderr.pipe;
assert.equal(stderrPipe.callCount, 1);
assert.strictEqual(stderrPipe.getCall(0).args[0], this.fakeLog);
},
'write() does not pipe to log if not set': function() {
this.encoder = new PngEncoder({spawn: this.fakeSpawn});
this.encoder.write(new Buffer('abc'));
assert.equal(this.fakeFfmpeg.stderr.pipe.callCount, 0);
},
'end() closes ffmpeg.stdin': function() {
this.encoder.write(new Buffer('abc'));
this.encoder.end();
assert.equal(this.fakeFfmpeg.stdin.end.callCount, 1);
},
'end() does not do anything if there is no ffmpeg yet': function() {
this.encoder.end();
},
});