Improve test coverage and cleanup.

This commit is contained in:
Braydon Fuller 2015-08-31 11:09:24 -04:00
parent f91fbe5e24
commit 53adaa7e6a
13 changed files with 347 additions and 355 deletions

View File

@ -1,31 +0,0 @@
'use strict';
var BitcoinNode = require('..').Node;
var chainlib = require('chainlib');
var log = chainlib.log;
log.debug = function() {};
var configuration = {
datadir: process.env.BITCORENODE_DIR || '~/.bitcoin',
network: 'testnet'
};
var node = new BitcoinNode(configuration);
var count = 0;
var interval;
node.on('ready', function() {
interval = setInterval(function() {
log.info('Sync Status: Tip:', node.chain.tip.hash, 'Height:', node.chain.tip.__height, 'Rate:', count/10, 'blocks per second');
count = 0;
}, 10000);
});
node.on('error', function(err) {
log.error(err);
});
node.chain.on('addblock', function(block) {
count++;
});

File diff suppressed because one or more lines are too long

View File

@ -1,26 +0,0 @@
{
"unspent": [
{
"txid": "0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098",
"outputIndex": 0
},
{
"txid": "8131ffb0a2c945ecaf9b9063e59558784f9c3a74741ce6ae2a18d0571dac15bb",
"outputIndex": 1
},
{
"txid": "226bbc4b1f851857f37aa96e9eb702946fc128b055e4decc684740005f5044cf",
"outputIndex": 0
}
],
"spent": [
{
"txid": "0437cd7f8525ceed2324359c2d0ba26006d92d856a9c20fa0241106ee5a597c9",
"outputIndex": 0
},
{
"txid": "fff2525b8931402dd09222c50775608f75787bd2b87e56995a7bdd30f79702c4",
"outputIndex": 1
}
]
}

File diff suppressed because one or more lines are too long

View File

@ -1,188 +0,0 @@
'use strict';
// These tests require a fully synced Bitcore Code data directory.
// To run the tests: $ mocha -R spec livenet.js
var chai = require('chai');
var bitcore = require('bitcore');
var bitcoind;
/* jshint unused: false */
var should = chai.should();
var assert = chai.assert;
var sinon = require('sinon');
var txData = require('./livenet-tx-data.json');
var blockData = require('./livenet-block-data.json');
var testTxData = require('./livenet-tx-data.json');
var spentData = require('./livenet-spents.json').spent;
var unspentData = require('./livenet-spents.json').unspent;
var testBlockData = require('./testnet-block-data.json');
describe('Basic Functionality', function() {
before(function(done) {
this.timeout(30000);
bitcoind = require('../').daemon({
datadir: process.env.BITCOINDJS_DIR || '~/.bitcoin',
});
bitcoind.on('error', function(err) {
bitcoind.log('error="%s"', err.message);
});
bitcoind.on('open', function(status) {
bitcoind.log('status="%s"', status);
});
console.log('Waiting for Bitcoin Core to initialize...');
bitcoind.on('ready', function() {
done();
});
});
after(function(done) {
this.timeout(20000);
bitcoind.stop(function(err, result) {
done();
});
});
describe('get transactions by hash', function() {
txData.forEach(function(data) {
var tx = bitcore.Transaction();
tx.fromString(data);
it('for tx ' + tx.hash, function(done) {
bitcoind.getTransaction(tx.hash, true, function(err, response) {
if (err) {
throw err;
}
assert(response.toString('hex') === data, 'incorrect tx data for ' + tx.hash);
done();
});
});
});
});
describe('determine if outpoint is unspent/spent', function() {
spentData.forEach(function(data) {
it('for spent txid ' + data.txid + ' and output ' + data.outputIndex, function() {
var spent = bitcoind.isSpent(data.txid, data.outputIndex, true);
spent.should.equal(true);
});
});
unspentData.forEach(function(data) {
it('for unspent txid ' + data.txid + ' and output ' + data.outputIndex, function() {
var spent = bitcoind.isSpent(data.txid, data.outputIndex, true);
spent.should.equal(false);
});
});
});
describe('get blocks by hash', function() {
blockData.forEach(function(data) {
var block = bitcore.Block.fromString(data);
it('block ' + block.hash, function(done) {
bitcoind.getBlock(block.hash, function(err, response) {
assert(response.toString('hex') === data, 'incorrect block data for ' + block.hash);
done();
});
});
});
});
describe('get blocks by height', function() {
var knownHeights = [
[0, '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f'],
[1, '00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048'],
[100000,'000000000003ba27aa200b1cecaad478d2b00432346c3f1f3986da1afd33e506'],
[314159, '00000000000000001bb82a7f5973618cfd3185ba1ded04dd852a653f92a27c45']
];
knownHeights.forEach(function(data) {
it('block at height ' + data[0], function(done) {
bitcoind.getBlock(data[0], function(err, response) {
if (err) {
throw err;
}
var block = bitcore.Block.fromBuffer(response);
block.hash.should.equal(data[1]);
done();
});
});
});
});
describe('get chain work', function() {
it('will get the total work for the genesis block via hash', function() {
var hash = '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f';
var work = bitcoind.getChainWork(hash);
work.should.equal('0000000000000000000000000000000000000000000000000000000100010001');
});
it('will get the total work for block #300000 via hash', function() {
var hash = '000000000000000082ccf8f1557c5d40b21edabb18d2d691cfbf87118bac7254';
var work = bitcoind.getChainWork(hash);
work.should.equal('000000000000000000000000000000000000000000005a7b3c42ea8b844374e9');
});
it('will return undefined for unknown block', function() {
var hash = 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff';
var work = bitcoind.getChainWork(hash);
should.equal(work, undefined);
});
});
describe('mempool functionality', function() {
var fromAddress = 'mszYqVnqKoQx4jcTdJXxwKAissE3Jbrrc1';
var utxo = {
address: fromAddress,
txId: 'a477af6b2667c29670467e4e0728b685ee07b240235771862318e29ddbe58458',
outputIndex: 0,
script: bitcore.Script.buildPublicKeyHashOut(fromAddress).toString(),
satoshis: 100000
};
var toAddress = 'mrU9pEmAx26HcbKVrABvgL7AwA5fjNFoDc';
var changeAddress = 'mgBCJAsvzgT2qNNeXsoECg2uPKrUsZ76up';
var changeAddressP2SH = '2N7T3TAetJrSCruQ39aNrJvYLhG1LJosujf';
var privateKey = 'cSBnVM4xvxarwGQuAfQFwqDg9k5tErHUHzgWsEfD4zdwUasvqRVY';
var private1 = '6ce7e97e317d2af16c33db0b9270ec047a91bff3eff8558afb5014afb2bb5976';
var private2 = 'c9b26b0f771a0d2dad88a44de90f05f416b3b385ff1d989343005546a0032890';
var tx = new bitcore.Transaction();
tx.from(utxo);
tx.to(toAddress, 50000);
tx.change(changeAddress);
tx.sign(privateKey);
it('will add an unchecked transaction', function() {
var added = bitcoind.addMempoolUncheckedTransaction(tx.serialize());
added.should.equal(true);
bitcoind.getTransaction(tx.hash, true, function(err, txBuffer) {
if(err) {
throw err;
}
var expected = tx.toBuffer().toString('hex');
txBuffer.toString('hex').should.equal(expected);
});
});
it('get outputs by address', function() {
var outputs = bitcoind.getMempoolOutputs(changeAddress);
var expected = [
{
script: 'OP_DUP OP_HASH160 073b7eae2823efa349e3b9155b8a735526463a0f OP_EQUALVERIFY OP_CHECKSIG',
satoshis: 40000,
txid: tx.hash,
outputIndex: 1
}
];
outputs.should.deep.equal(expected);
});
});
});

File diff suppressed because one or more lines are too long

View File

@ -1,5 +0,0 @@
[
"0100000001eccd472c53ec7827eb8952a32d001ca95072ebe0a530f09cdf7219c0ce3f47be010000006a4730440220499cf8379c82301df2295c1581e1d683fec8cc201097efef748fcf3536532882022048c35b24485ec57f387745daf9fc50414ba76e50e914b53b9070f0a4a552f662012102a82fb2ce6e2ea8abb977d9825a2360c9447003dc91da5b8ffa5fc4b3c7808f3fffffffff020001b2c4000000001976a91442f0eb6de4628a6a7ae1afc85b027ff5e0aa25de88ac00437f1f690000001976a91443a3fc9d2ec090a08775957c364073e8b69cfe0688ac00000000",
"01000000021ae3aa69180bbf3d898cd31232224cfe6a2f21ff34051b6fc14f99528e2f0aee010000006b483045022100c9e8656a407fc1fb379b1669abbed3415483bcd20929ebc7fa2f7ecf7c7a7f7b022021dca2336f14df90f201ff8caa8d7a4b8e1760d07afecef880e0cfcbd13756d70121038f4478ad50111c8d04c692fcb6ce560f617a1d01b3056436ebf906d802a422afffffffff1ae3aa69180bbf3d898cd31232224cfe6a2f21ff34051b6fc14f99528e2f0aee030000008a4730440220275f9ab3083c78b368f1e33341275c776fc4af4105ee2646004e9ffb4cba639302202739d0063726a7bcea6681172892c8ab8c1c0b09b1a4d5ed1dc0cf9bea7b18990141048dcb436c4c027e8a5826bdf3c8b6cb326abe66a2d34a18aa473442d8c535f902da45df071964fc8304658b20f9dd1ed241dc48578bf775624a9bd8c52b92c389ffffffff02402b9b00000000001976a914f4f065395c82c6f28d3c73cef113d6da0f90d82a88ac5423f984000000001976a9145af0fe772e1600100b2000f8279f78ce66b7e1d588ac00000000",
"0100000002741453f89d091381329178b3d38cc213c21caede56f5a4a6b74e16ae9bd78b20000000006b483045022100bc0fa3e50ba16589664fd368139c02e3a9da55e20cceed340645b00f6466edac022068cad98f90006534afa2c38551248c6161861e32cb1af6ee1d0f75886263f9c20121038e9dac10e76c6c48a9b791de55f3ea009ee5d10532088f2eb9991d55b03b44e8ffffffff092910ede6e477e9589f8ce00807154378fcbd482d630b2c8cdd10243e74db79010000006b4830450221009cc13ef1acfdfc4535d888b1ea495b3c543e4fabdf38ce8cde4a37171136977c02201a0571e3ab3fd70ca4d97193fcd7999b35760ea4cac404edd1e50a338e50a28d012102e397fa30f882d076e393deec070d423138bd9544aa4cb53450b609713bb327aaffffffff02d5420400000000001976a914171e633a137d5c2275174380c6ca761d7e30365f88acb01a0200000000001976a914263ca88fd638fdb0e2ee8e2a16ec21ecea7a3d7e88ac00000000"
]

View File

@ -12,7 +12,7 @@ function getDefaultConfig() {
config: {
datadir: process.env.BITCORENODE_DIR || path.resolve(process.env.HOME, '.bitcoin'),
network: process.env.BITCORENODE_NETWORK || 'livenet',
port: process.env.BITCORENODE_PORT || 3001,
port: Number(process.env.BITCORENODE_PORT) || 3001,
services: ['bitcoind', 'db', 'address', 'web']
}
};

View File

@ -6,6 +6,7 @@ var mkdirp = require('mkdirp');
var fs = require('fs');
var bitcore = require('bitcore');
var $ = bitcore.util.preconditions;
var _ = bitcore.deps._;
var index = require('../');
var log = index.log;
var Service = require('../service');
@ -21,37 +22,14 @@ function Bitcoin(options) {
return new Bitcoin(options);
}
var self = this;
Service.call(this, options);
if (Object.keys(this.instances).length) {
throw new Error('Bitcoin cannot be instantiated more than once.');
}
$.checkState(this.node.datadir, 'Node is missing datadir property');
Object.keys(exports).forEach(function(key) {
self[key] = exports[key];
});
}
util.inherits(Bitcoin, Service);
Bitcoin.dependencies = [];
Bitcoin.instances = {};
Bitcoin.prototype.instances = Bitcoin.instances;
Bitcoin.__defineGetter__('global', function() {
return Bitcoin.instances[Object.keys(Bitcoin.instances)[0]];
});
Bitcoin.prototype.__defineGetter__('global', function() {
return Bitcoin.global;
});
Bitcoin.DEFAULT_CONFIG = 'whitelist=127.0.0.1\n' + 'txindex=1\n';
Bitcoin.prototype._loadConfiguration = function() {
@ -93,16 +71,62 @@ Bitcoin.prototype._loadConfiguration = function() {
);
};
Bitcoin.prototype._onTipUpdate = function(result) {
if (result) {
// Emit and event that the tip was updated
this.height = result;
this.emit('tip', result);
// TODO stopping status
if(!this.node.stopping) {
var percentage = this.syncPercentage();
log.info('Bitcoin Core Daemon New Height:', this.height, 'Percentage:', percentage);
}
// Recursively wait until the next update
bindings.onTipUpdate(this._onTipUpdate.bind(this));
}
};
Bitcoin.prototype._registerEventHandlers = function() {
var self = this;
// Set the height and emit a new tip
bindings.onTipUpdate(self._onTipUpdate.bind(this));
// Register callback function to handle incoming transactions
bindings.startTxMon(function(txs) {
for(var i = 0; i < txs.length; i++) {
self.emit('tx', txs[i]);
}
});
};
Bitcoin.prototype._onReady = function(result, callback) {
var self = this;
self._registerEventHandlers();
var info = self.getInfo();
self.height = info.blocks;
self.getBlock(0, function(err, block) {
if (err) {
return callback(err);
}
self.genesisBuffer = block;
self.emit('ready', result);
log.info('Bitcoin Daemon Ready');
setImmediate(callback);
});
};
Bitcoin.prototype.start = function(callback) {
var self = this;
this._loadConfiguration();
if (this.instances[this.datadir]) {
return callback(new Error('Bitcoin already started'));
}
this.instances[this.datadir] = true;
bindings.start({
datadir: this.node.datadir,
network: this.node.network.name
@ -110,48 +134,12 @@ Bitcoin.prototype.start = function(callback) {
if(err) {
return callback(err);
}
self._started = true;
// Wait until the block chain is ready
bindings.onBlocksReady(function(err, result) {
function onTipUpdateListener(result) {
if (result) {
// Emit and event that the tip was updated
self.height = result;
self.emit('tip', result);
// TODO stopping status
if(!self.stopping) {
var percentage = self.syncPercentage();
log.info('Bitcoin Core Daemon New Height:', self.height, 'Percentage:', percentage);
}
// Recursively wait until the next update
bindings.onTipUpdate(onTipUpdateListener);
}
if (err) {
return callback(err);
}
bindings.onTipUpdate(onTipUpdateListener);
bindings.startTxMon(function(txs) {
for(var i = 0; i < txs.length; i++) {
self.emit('tx', txs[i]);
}
});
// Set the current chain height
var info = self.getInfo();
self.height = info.blocks;
// Get the genesis block
self.getBlock(0, function(err, block) {
self.genesisBuffer = block;
self.emit('ready', result);
log.info('Bitcoin Daemon Ready');
setImmediate(callback);
});
self._onReady(result, callback);
});
});
};

View File

@ -4,7 +4,6 @@ var async = require('async');
var levelup = require('levelup');
var bitcore = require('bitcore');
var Transaction = bitcore.Transaction;
var BufferWriter = bitcore.encoding.BufferWriter;
Transaction.prototype.populateInputs = function(db, poolTransactions, callback) {
var self = this;
@ -58,13 +57,4 @@ Transaction.prototype._checkSpent = function(db, input, poolTransactions, callba
});
};
Transaction.manyToBuffer = function(transactions) {
var bw = new BufferWriter();
var count = transactions.length;
for(var i = 0; i < count; i++) {
transactions[i].toBufferWriter(bw);
}
return bw.concat();
};
module.exports = Transaction;

View File

@ -36,7 +36,7 @@
"upload": "node bin/upload.js",
"start": "node bin/start.js",
"test": "NODE_ENV=test mocha -R spec --recursive",
"coverage": "istanbul cover _mocha -- --recursive",
"coverage": "NODE_ENV=test istanbul cover _mocha -- --recursive",
"libbitcoind": "node bin/start-libbitcoind.js"
},
"tags": [

View File

@ -0,0 +1,32 @@
'use strict';
var should = require('chai').should();
var defaultConfig = require('../../lib/scaffold/default-config');
describe('#defaultConfig', function() {
it('will return expected configuration', function() {
var cwd = process.cwd();
var home = process.env.HOME;
var info = defaultConfig();
info.path.should.equal(cwd);
info.config.datadir.should.equal(home + '/.bitcoin');
info.config.network.should.equal('livenet');
info.config.port.should.equal(3001);
info.config.services.should.deep.equal(['bitcoind', 'db', 'address', 'web']);
});
it('will return expected configuration from environment variables', function() {
var cwd = process.cwd();
process.env.BITCORENODE_DIR = '/home/bitcore-node/.bitcoin';
process.env.BITCORENODE_NETWORK = 'testnet';
process.env.BITCORENODE_PORT = 3002;
var info = defaultConfig();
info.path.should.equal(cwd);
info.config.datadir.should.equal('/home/bitcore-node/.bitcoin');
info.config.network.should.equal('testnet');
info.config.port.should.equal(3002);
info.config.services.should.deep.equal(['bitcoind', 'db', 'address', 'web']);
});
});

View File

@ -1,17 +1,14 @@
'use strict';
var should = require('chai').should();
var sinon = require('sinon');
var proxyquire = require('proxyquire');
var fs = require('fs');
var sinon = require('sinon');
var readFileSync = sinon.stub().returns(fs.readFileSync(__dirname + '/../data/bitcoin.conf'));
var BitcoinService = proxyquire('../../lib/services/bitcoind', {
fs: {
readFileSync: sinon.stub().returns(fs.readFileSync(__dirname + '/../data/bitcoin.conf'))
}
});
var BadBitcoin = proxyquire('../../lib/services/bitcoind', {
fs: {
readFileSync: sinon.stub().returns(fs.readFileSync(__dirname + '/../data/badbitcoin.conf'))
readFileSync: readFileSync
}
});
@ -24,9 +21,33 @@ describe('Bitcoin Service', function() {
}
}
};
describe('@constructor', function() {
it('will create an instance', function() {
var bitcoind = new BitcoinService(baseConfig);
should.exist(bitcoind);
});
it('will create an instance without `new`', function() {
var bitcoind = BitcoinService(baseConfig);
should.exist(bitcoind);
});
});
describe('@dependencies', function() {
it('will have no dependencies', function() {
BitcoinService.dependencies.should.deep.equal([]);
});
});
describe('#_loadConfiguration', function() {
it('will parse a bitcoin.conf file', function() {
var bitcoind = new BitcoinService(baseConfig);
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
fs: {
readFileSync: readFileSync,
existsSync: sinon.stub().returns(true)
},
mkdirp: {
sync: sinon.stub()
}
});
var bitcoind = new TestBitcoin(baseConfig);
bitcoind._loadConfiguration({datadir: process.env.HOME + '/.bitcoin'});
should.exist(bitcoind.configuration);
bitcoind.configuration.should.deep.equal({
@ -40,11 +61,238 @@ describe('Bitcoin Service', function() {
});
});
it('should throw an exception if txindex isn\'t enabled in the configuration', function() {
var bitcoind = new BadBitcoin(baseConfig);
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
fs: {
readFileSync: sinon.stub().returns(fs.readFileSync(__dirname + '/../data/badbitcoin.conf')),
existsSync: sinon.stub().returns(true),
},
mkdirp: {
sync: sinon.stub()
}
});
var bitcoind = new TestBitcoin(baseConfig);
(function() {
bitcoind._loadConfiguration({datadir: './test'});
}).should.throw('Txindex option');
});
});
});
describe('#_registerEventHandlers', function() {
it('will emit tx with transactions from bindings', function(done) {
var transaction = {};
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
fs: {
readFileSync: readFileSync
},
bindings: function(name) {
name.should.equal('bitcoind.node');
return {
onTipUpdate: sinon.stub(),
startTxMon: sinon.stub().callsArgWith(0, [transaction])
};
}
});
var bitcoind = new TestBitcoin(baseConfig);
bitcoind.on('tx', function(tx) {
tx.should.equal(transaction);
done();
});
bitcoind._registerEventHandlers();
});
it('will emit tip from bindings', function(done) {
var height = 1;
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
fs: {
readFileSync: readFileSync
},
bindings: function(name) {
name.should.equal('bitcoind.node');
return {
syncPercentage: function() {
return height * 10;
},
onTipUpdate: function(callback) {
if (height >= 10) {
return callback(undefined);
}
setImmediate(function() {
callback(height++);
});
},
startTxMon: sinon.stub()
};
}
});
var bitcoind = new TestBitcoin(baseConfig);
var tipCallCount = 0;
bitcoind.on('tip', function(height) {
should.exist(height);
tipCallCount++;
if (height === 9) {
tipCallCount.should.equal(9);
done();
}
});
bitcoind._registerEventHandlers();
});
});
describe('#_onReady', function(done) {
var genesisBuffer = new Buffer('0100000043497fd7f826957108f4a30fd9cec3aeba79972084e90ead01ea330900000000bac8b0fa927c0ac8234287e33c5f74d38d354820e24756ad709d7038fc5f31f020e7494dffff001d03e4b6720101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0e0420e7494d017f062f503253482fffffffff0100f2052a010000002321021aeaf2f8638a129a3156fbe7e5ef635226b0bafd495ff03afe2c843d7e3a4b51ac00000000', 'hex');
it('will emit ready and set the height and genesisBuffer', function(done) {
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
fs: {
readFileSync: readFileSync
},
bindings: function(name) {
name.should.equal('bitcoind.node');
return {
onTipUpdate: sinon.stub(),
startTxMon: sinon.stub(),
getInfo: sinon.stub().returns({
blocks: 101
}),
getBlock: sinon.stub().callsArgWith(1, null, genesisBuffer)
};
}
});
var bitcoind = new TestBitcoin(baseConfig);
bitcoind._registerEventHandlers = sinon.stub();
var result = {};
var readyCallCount = 0;
bitcoind.on('ready', function() {
readyCallCount++;
});
bitcoind._onReady(result, function(err) {
if (err) {
throw err;
}
bitcoind._registerEventHandlers.callCount.should.equal(1);
readyCallCount.should.equal(1);
bitcoind.genesisBuffer.should.equal(genesisBuffer);
bitcoind.height.should.equal(101);
done();
});
});
});
describe('#start', function() {
it('call bindings start with the correct arguments', function(done) {
var startCallCount = 0;
var start = function(obj, cb) {
startCallCount++;
obj.datadir.should.equal('testdir');
obj.network.should.equal('regtest');
cb();
};
var onBlocksReady = sinon.stub().callsArg(0);
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
fs: {
readFileSync: readFileSync
},
bindings: function(name) {
name.should.equal('bitcoind.node');
return {
start: start,
onBlocksReady: onBlocksReady
};
}
});
var bitcoind = new TestBitcoin(baseConfig);
bitcoind._loadConfiguration = sinon.stub();
bitcoind._onReady = sinon.stub().callsArg(1);
bitcoind.start(function(err) {
should.not.exist(err);
bitcoind._loadConfiguration.callCount.should.equal(1);
startCallCount.should.equal(1);
onBlocksReady.callCount.should.equal(1);
bitcoind._onReady.callCount.should.equal(1);
done();
});
});
it('will give an error from bindings.start', function(done) {
var start = sinon.stub().callsArgWith(1, new Error('test'));
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
fs: {
readFileSync: readFileSync
},
bindings: function(name) {
name.should.equal('bitcoind.node');
return {
start: start
};
}
});
var bitcoind = new TestBitcoin(baseConfig);
bitcoind._loadConfiguration = sinon.stub();
bitcoind.start(function(err) {
should.exist(err);
err.message.should.equal('test');
done();
});
});
it('will give an error from bindings.onBlocksReady', function(done) {
var start = sinon.stub().callsArgWith(1, null);
var onBlocksReady = sinon.stub().callsArgWith(0, new Error('test'));
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
fs: {
readFileSync: readFileSync
},
bindings: function(name) {
name.should.equal('bitcoind.node');
return {
start: start,
onBlocksReady: onBlocksReady
};
}
});
var bitcoind = new TestBitcoin(baseConfig);
bitcoind._onReady = sinon.stub().callsArg(1);
bitcoind._loadConfiguration = sinon.stub();
bitcoind.start(function(err) {
should.exist(err);
err.message.should.equal('test');
done();
});
});
});
describe('#stop', function() {
it('will call bindings stop', function() {
var stop = sinon.stub().callsArgWith(0, null, 'status');
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
fs: {
readFileSync: readFileSync
},
bindings: function(name) {
name.should.equal('bitcoind.node');
return {
stop: stop
};
}
});
var bitcoind = new TestBitcoin(baseConfig);
bitcoind.stop(function(err, status) {
stop.callCount.should.equal(1);
should.not.exist(err);
});
});
it('will give an error from bindings stop', function() {
var stop = sinon.stub().callsArgWith(0, new Error('test'));
var TestBitcoin = proxyquire('../../lib/services/bitcoind', {
fs: {
readFileSync: readFileSync
},
bindings: function(name) {
name.should.equal('bitcoind.node');
return {
stop: stop
};
}
});
var bitcoind = new TestBitcoin(baseConfig);
bitcoind.stop(function(err) {
stop.callCount.should.equal(1);
should.exist(err);
err.message.should.equal('test');
});
});
});
});