diff --git a/test/specs/serial-connection.spec.js b/test/specs/serial-connection.spec.js index 964a7ed4..5502e5e4 100644 --- a/test/specs/serial-connection.spec.js +++ b/test/specs/serial-connection.spec.js @@ -3,7 +3,66 @@ -var SerialConnection = require('./resol-vbus').SerialConnection; +var Duplex = require('stream').Duplex; + + +var Q = require('q'); +var serialPort = require('serialport'); + + +var vbus = require('./resol-vbus'); + + + +var SerialConnection = vbus.SerialConnection; + + + +var SerialPortStub = vbus.extend(Duplex, { + + constructor: function() { + var _this = this; + + Duplex.call(this); + + process.nextTick(function() { + _this.emit('open'); + }); + }, + + close: function() { + // nop + }, + + _read: function() { + // nop + }, + +}); + + + +var testConnection = function(done, callback) { + var connection = new SerialConnection({ + }); + + var originalSerialPort = serialPort.SerialPort; + + serialPort.SerialPort = sinon.spy(SerialPortStub); + + Q.fcall(function() { + expect(connection.connectionState).to.equal(SerialConnection.STATE_DISCONNECTED); + + return callback(connection); + }).finally(function() { + serialPort.SerialPort = originalSerialPort; + connection.disconnect(); + }).done(function() { + done(); + }, function(err) { + done(err); + }); +}; @@ -12,12 +71,132 @@ describe('SerialConnection', function() { describe('constructor', function() { it('should be a constructor function', function() { - expect(SerialConnection).to.be.a('function'); + expect(SerialConnection) + .to.be.a('function') + .that.has.a.property('extend') + .that.is.a('function'); + }); + + it('should have reasonable defaults', function() { + var connection = new SerialConnection(); + + expect(connection) + .to.have.a.property('channel') + .that.is.equal(0); + expect(connection) + .to.have.a.property('selfAddress') + .that.is.equal(0x0020); + expect(connection) + .to.have.a.property('path') + .that.is.equal(null); }); }); - xit('should perform tests...', function() { + describe('#connect', function() { + + it('should be a method', function() { + expect(SerialConnection.prototype).to.have.a.property('connect').that.is.a('function'); + }); + + it('should work correctly if disconnected', function(done) { + testConnection(done, function(connection, endpoint) { + var onConnectionState = sinon.spy(); + + connection.on('connectionState', onConnectionState); + + return Q.fcall(function() { + return connection.connect(); + }).then(function() { + expect(connection.connectionState).to.equal(SerialConnection.STATE_CONNECTED); + expect(onConnectionState.callCount).to.equal(2); + expect(onConnectionState.firstCall.args [0]).to.equal(SerialConnection.STATE_CONNECTING); + expect(onConnectionState.secondCall.args [0]).to.equal(SerialConnection.STATE_CONNECTED); + }).finally(function() { + connection.removeListener('connectionState', onConnectionState); + }); + }); + }); + + it('should throw if not disconnected', function(done) { + testConnection(done, function(connection, endpoint) { + return Q.fcall(function() { + return connection.connect(); + }).then(function() { + expect(function() { + connection.connect(); + }).to.throw(); + }); + }); + }); + + }); + + describe('#disconnect', function() { + + it('should be a method', function() { + expect(SerialConnection.prototype).to.have.a.property('disconnect').that.is.a('function'); + }); + + it('should work correctly if disconnected', function(done) { + testConnection(done, function(connection) { + connection.disconnect(); + + expect(connection.connectionState).to.equal(SerialConnection.STATE_DISCONNECTED); + }); + }); + + it('should work correctly if connected', function(done) { + testConnection(done, function(connection) { + var onConnectionState = sinon.spy(); + + connection.on('connectionState', onConnectionState); + + return Q.fcall(function() { + return connection.connect(); + }).then(function() { + return connection.disconnect(); + }).finally(function() { + connection.removeListener('connectionState', onConnectionState); + }); + }); + }); + + }); + + describe('Automatic reconnection', function() { + + it('should reconnect when connected', function(done) { + testConnection(done, function(connection) { + var onConnectionState = sinon.spy(); + + connection.on('connectionState', onConnectionState); + + return Q.fcall(function() { + return connection.connect(); + }).then(function() { + return connection.createConnectedPromise(); + }).then(function(socket) { + expect(onConnectionState.callCount).to.equal(2); + expect(onConnectionState.firstCall.args [0]).to.equal(SerialConnection.STATE_CONNECTING); + expect(onConnectionState.secondCall.args [0]).to.equal(SerialConnection.STATE_CONNECTED); + + onConnectionState.reset(); + + connection.serialPort.emit('error'); + }).then(function() { + return connection.createConnectedPromise(); + }).then(function() { + expect(onConnectionState.callCount).to.equal(3); + expect(onConnectionState.firstCall.args [0]).to.equal(SerialConnection.STATE_INTERRUPTED); + expect(onConnectionState.secondCall.args [0]).to.equal(SerialConnection.STATE_RECONNECTING); + expect(onConnectionState.thirdCall.args [0]).to.equal(SerialConnection.STATE_CONNECTED); + }).finally(function() { + connection.removeListener('connectionState', onConnectionState); + }); + }); + + }); });