diff --git a/.jshintrc b/.jshintrc index 948f3b6..48c745a 100644 --- a/.jshintrc +++ b/.jshintrc @@ -32,7 +32,6 @@ "afterEach", "it", "inject", - "expect", "$", "io", "app", diff --git a/lib/PeerSync.js b/lib/PeerSync.js index 08561ac..49526cf 100644 --- a/lib/PeerSync.js +++ b/lib/PeerSync.js @@ -14,22 +14,25 @@ function spec() { PeerSync.prototype.init = function(config, cb) { - + if (!config) config = {}; var that = this; var network = config && (config.network || 'testnet'); - that.peerdb = undefined; - that.sync = new Sync({ + this.verbose = config.verbose; + this.peerdb = undefined; + this.sync = new Sync({ networkName: network }); - that.sync.init(config, function() { - that.PeerManager = require('bitcore/PeerManager').createClass({ - config: { - network: network - } - }); - that.load_peers(); + + this.PeerManager = require('bitcore/PeerManager').createClass({ + config: { + network: network + } + }); + this.peerman = new this.PeerManager(); + this.load_peers(); + this.sync.init(config, function() { return cb(); }); }; @@ -50,9 +53,12 @@ function spec() { }; PeerSync.prototype.handle_inv = function(info) { + var self = this; var invs = info.message.invs; invs.forEach(function(inv) { - console.log('[p2p_sync] Handle inv for a ' + CoinConst.MSG.to_str(inv.type)); + if (self.verbose) { + console.log('[p2p_sync] Handle inv for a ' + CoinConst.MSG.to_str(inv.type)); + } }); // TODO: should limit the invs to objects we haven't seen yet info.conn.sendGetData(invs); @@ -60,10 +66,12 @@ function spec() { PeerSync.prototype.handle_tx = function(info) { var tx = info.message.tx.getStandardizedObject(); - console.log('[p2p_sync] Handle tx: ' + tx.hash); + if (this.verbose) { + console.log('[p2p_sync] Handle tx: ' + tx.hash); + } this.sync.storeTxs([tx.hash], null, function(err) { if (err) { - console.log('[p2p_sync] Error in handle TX: ' + err); + console.log('[p2p_sync] Error in handle TX: ' + JSON.stringify(err)); } }); }; @@ -71,7 +79,9 @@ function spec() { PeerSync.prototype.handle_block = function(info) { var block = info.message.block; var blockHash = coinUtil.formatHashFull(block.calcHash()); - console.log('[p2p_sync] Handle block: ' + blockHash); + if (this.verbose) { + console.log('[p2p_sync] Handle block: ' + blockHash); + } var tx_hashes = block.txs.map(function(tx) { @@ -93,27 +103,34 @@ function spec() { PeerSync.prototype.handle_connected = function(data) { var peerman = data.pm; var peers_n = peerman.peers.length; - console.log('[p2p_sync] Connected to ' + peers_n + ' peer' + (peers_n !== 1 ? 's': '')); + if (this.verbose) { + console.log('[p2p_sync] Connected to ' + peers_n + ' peer' + (peers_n !== 1 ? 's': '')); + } }; PeerSync.prototype.run = function() { var self = this; - var peerman = new this.PeerManager(); this.peerdb.forEach(function(datum) { var peer = new Peer(datum.ipv4, datum.port); - peerman.addPeer(peer); + self.peerman.addPeer(peer); }); - peerman.on('connection', function(conn) { + this.peerman.on('connection', function(conn) { conn.on('inv', self.handle_inv.bind(self)); conn.on('block', self.handle_block.bind(self)); conn.on('tx', self.handle_tx.bind(self)); }); - peerman.on('connect', self.handle_connected.bind(self)); + this.peerman.on('connect', self.handle_connected.bind(self)); - peerman.start(); + this.peerman.start(); }; + + PeerSync.prototype.close = function() { + this.sync.close(); + }; + + return PeerSync; } diff --git a/lib/Sync.js b/lib/Sync.js index 941ac37..520ba14 100644 --- a/lib/Sync.js +++ b/lib/Sync.js @@ -73,7 +73,9 @@ function spec() { that.opts = opts; if (!(opts && opts.skip_db_connection)) { - mongoose.connect(config.db, {server: {auto_reconnect: true}} ); + if (!mongoose.connection) { + mongoose.connect(config.db, {server: {auto_reconnect: true}} ); + } this.db = mongoose.connection; @@ -94,7 +96,6 @@ function spec() { Sync.prototype.close = function() { if (!(this.opts && this.opts.skip_db_connection)) { - console.log('closing connection'); this.db.close(); } }; diff --git a/package.json b/package.json index 3ddffc8..c7ce381 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,8 @@ "view-helpers": "latest", "socket.io": "~0.9.16", "moment": "~2.5.0", - "sinon": "~1.7.3" + "sinon": "~1.7.3", + "chai": "~1.8.1" }, "devDependencies": { "grunt-contrib-watch": "latest", diff --git a/test/lib/PeerSync.js b/test/lib/PeerSync.js index de6b49b..c7c48e3 100644 --- a/test/lib/PeerSync.js +++ b/test/lib/PeerSync.js @@ -1,13 +1,77 @@ 'use strict'; -var assert = require('assert'); +var chai = require('chai'), + expect = chai.expect, + sinon = require('sinon'); + var PeerSync = require('../../lib/PeerSync.js').class(); -describe('Unit testing PeerSync', function() { - var ps = new PeerSync(); +describe('PeerSync', function() { + var ps; + + beforeEach(function() { + ps = new PeerSync(); + ps.init({verbose: false}); + }); + afterEach(function(){ + ps.close(); + }); + describe('#init()', function() { it('should return with no errors', function() { - assert.doesNotThrow(function(){ - ps.init(); - }); + var other_ps = new PeerSync(); + expect(other_ps.init.bind(other_ps)).not.to.throw(Error); + other_ps.close(); + }); + }); + + describe('#handle_inv()', function() { + var inv_info = { + message: {invs: []}, + conn: {sendGetData: sinon.spy()} + }; + it('should return with no errors', function(){ + expect(function() { + ps.handle_inv(inv_info); + }).not.to.throw(Error); + }); + it('should call sendGetData', function() { + ps.handle_inv(inv_info); + expect(inv_info.conn.sendGetData.calledTwice).to.be.ok; + }); + }); + + describe('#handle_tx()', function() { + var tx_info = { + message: { tx: {getStandardizedObject: function(){ + return {hash: 'dac28b5c5e70c16942718f3a22438348c1b709e01d398795fce8fc455178b973'};}}} + }; + it('should call storeTxs', function(){ + var spy = sinon.spy(ps.sync, 'storeTxs'); + ps.handle_tx(tx_info); + expect(spy.calledOnce).to.be.ok; + }); + }); + + describe('#handle_block()', function() { + var block_info = { + message: { block: {calcHash: function(){ + return new Buffer('01234'); + }, txs: [{hash: new Buffer('cabafeca')}, {hash: new Buffer('bacacafe')}]}} + }; + it('should call storeBlock', function(){ + var spy = sinon.spy(ps.sync, 'storeBlock'); + ps.handle_block(block_info); + expect(spy.calledOnce).to.be.ok; + }); + }); + + describe('#run()', function() { + it('should setup peerman', function() { + var startSpy = sinon.spy(ps.peerman, 'start'); + var onSpy = sinon.spy(ps.peerman, 'on'); + ps.run(); + + expect(startSpy.called).to.be.ok; + expect(onSpy.called).to.be.ok; }); }); });