Modified DevFunds to “factory pattern”

Added a “factory pattern” to DevFunds to allow for async calls to be made during object construction. This allows for `web3.eth.getAccounts` to be called and the `accounts` property assigned on instantiation.

This modification allows each unit test case to be run independently of the others.
This commit is contained in:
emizzle 2018-08-01 11:35:42 +10:00
parent 7cb9cd5622
commit 9b41fa8ac2
4 changed files with 61 additions and 54 deletions

View File

@ -188,9 +188,10 @@ Blockchain.prototype.run = function() {
}; };
Blockchain.prototype.createFundAndUnlockAccounts = function(cb) { Blockchain.prototype.createFundAndUnlockAccounts = function(cb) {
let devFunds = new DevFunds({blockchainConfig: this.config}); DevFunds.new({blockchainConfig: this.config}).then(devFunds => {
devFunds.createFundAndUnlockAccounts((err) => { devFunds.createFundAndUnlockAccounts((err) => {
cb(err); cb(err);
});
}); });
}; };

View File

@ -19,6 +19,20 @@ class DevFunds {
this.logger = options.logger || console; this.logger = options.logger || console;
} }
static async new(options){
const df = new DevFunds(options);
await df._init();
return df;
}
async _init () {
const accounts = await this.web3.eth.getAccounts();
this.web3.eth.defaultAccount = accounts[0];
if (accounts.length > 1) {
this.accounts = accounts.slice(1);
}
}
_sendTx() { _sendTx() {
if (this.networkId !== 1337) { if (this.networkId !== 1337) {
return; return;
@ -27,7 +41,7 @@ class DevFunds {
} }
// trigger regular txs due to a bug in geth and stuck transactions in --dev mode // trigger regular txs due to a bug in geth and stuck transactions in --dev mode
regularTxs(cb) { _regularTxs(cb) {
const self = this; const self = this;
self.web3.eth.net.getId().then((networkId) => { self.web3.eth.net.getId().then((networkId) => {
self.networkId = networkId; self.networkId = networkId;
@ -42,21 +56,11 @@ class DevFunds {
}); });
} }
regularUnlocks() { _regularUnlocks() {
const self = this; const self = this;
setInterval(function () { self.unlockAccounts(self.password, () => { }); }, 20000); setInterval(function () { self.unlockAccounts(self.password, () => { }); }, 20000);
} }
getCurrentAccounts(cb) {
this.web3.eth.getAccounts().then((accounts) => {
this.web3.eth.defaultAccount = accounts[0];
if (accounts.length > 1) {
this.accounts = accounts.slice(1);
}
cb();
});
}
createAccounts(numAccounts, password, cb) { createAccounts(numAccounts, password, cb) {
const numAccountsToCreate = numAccounts - (this.accounts.length + 1); const numAccountsToCreate = numAccounts - (this.accounts.length + 1);
if (numAccountsToCreate === 0) return cb(); if (numAccountsToCreate === 0) return cb();
@ -95,9 +99,6 @@ class DevFunds {
return cb(); return cb();
} }
async.waterfall([ async.waterfall([
(next) => {
this.getCurrentAccounts(next);
},
(next) => { (next) => {
this.createAccounts(this.numAccounts, this.password, next); this.createAccounts(this.numAccounts, this.password, next);
}, },
@ -105,8 +106,8 @@ class DevFunds {
this.unlockAccounts(this.password, next); this.unlockAccounts(this.password, next);
}, },
(next) => { (next) => {
this.regularTxs(); this._regularTxs();
this.regularUnlocks(); this._regularUnlocks();
this.fundAccounts(this.balance, next); this.fundAccounts(this.balance, next);
} }
], cb); ], cb);

View File

@ -1,4 +1,4 @@
/*global describe, it*/ /*global describe, it, before*/
const assert = require('assert'); const assert = require('assert');
let TestLogger = require('../lib/tests/test_logger.js'); let TestLogger = require('../lib/tests/test_logger.js');
const Web3 = require('web3'); const Web3 = require('web3');
@ -53,36 +53,43 @@ describe('embark.DevFunds', function () {
describe('#create, fund, and unlock accounts', function () { describe('#create, fund, and unlock accounts', function () {
let provider = new FakeIpcProvider(); let provider = new FakeIpcProvider();
let devFunds = new DevFunds({blockchainConfig: config, provider: provider, logger: new TestLogger({})});
const web3 = new Web3(provider); const web3 = new Web3(provider);
let devFunds;
before(async () => {
provider.injectResult(['0x47d33b27bb249a2dbab4c0612bf9caf4c1950855']); // getAccounts: return --dev account
devFunds = await DevFunds.new({blockchainConfig: config, provider: provider, logger: new TestLogger({})});
});
it('should create correct number of accounts', function (done) { it('should create correct number of accounts', function (done) {
provider.injectResult(['0x47d33b27bb249a2dbab4c0612bf9caf4c1950855']); // getAccounts - return --dev account provider.injectResult('0x11f4d0a3c12e86b4b5f39b213f7e19d048276dae'); // createAccount #1
devFunds.getCurrentAccounts(() => { provider.injectResult('0x22f4d0a3c12e86b4b5f39b213f7e19d048276dab'); // createAccount #2
provider.injectResult('0x11f4d0a3c12e86b4b5f39b213f7e19d048276dae'); // createAccount #1 devFunds.createAccounts(config.account.numAccounts, 'test_password', (err) => {
provider.injectResult('0x22f4d0a3c12e86b4b5f39b213f7e19d048276dab'); // createAccount #2 assert.equal(err, null);
devFunds.createAccounts(config.account.numAccounts, 'test_password', (err) => { // TODO: make FakeIpcProvider smart enough to keep track of created accounts
assert.equal(err, null); provider.injectResult(['0x47d33b27bb249a2dbab4c0612bf9caf4c1950855', '0x11f4d0a3c12e86b4b5f39b213f7e19d048276dae', '0x22f4d0a3c12e86b4b5f39b213f7e19d048276dab']);
// TODO: make FakeIpcProvider smart enough to keep track of created accounts web3.eth.getAccounts().then((accts) => {
provider.injectResult(['0x47d33b27bb249a2dbab4c0612bf9caf4c1950855', '0x11f4d0a3c12e86b4b5f39b213f7e19d048276dae', '0x22f4d0a3c12e86b4b5f39b213f7e19d048276dab']); assert.equal(accts.length, config.account.numAccounts);
assert.strictEqual(accts[0], '0x47D33b27Bb249a2DBab4C0612BF9CaF4C1950855'); // --dev acct
web3.eth.getAccounts().then((accts) => { assert.strictEqual(accts[1], '0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe'); // created acct #1
assert.equal(accts.length, config.account.numAccounts); assert.strictEqual(accts[2], '0x22F4d0A3C12E86b4b5F39B213f7e19D048276DAb'); // created acct #2
assert.strictEqual(accts[0], '0x47D33b27Bb249a2DBab4C0612BF9CaF4C1950855'); done();
assert.strictEqual(accts[1], '0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe');
assert.strictEqual(accts[2], '0x22F4d0A3C12E86b4b5F39B213f7e19D048276DAb');
done();
});
}); });
}); });
}); });
it('should unlock accounts', function (done) { it('should unlock accounts', function (done) {
provider.injectResult(true); // account #1 unlock result if (devFunds.accounts.length === 0) {
provider.injectResult(true); // account #2 unlock result assert.equal(true, true, "no accounts to unlock");
return done();
}
devFunds.accounts.forEach(_acct => {
provider.injectResult(true); // account unlock result
});
devFunds.unlockAccounts(devFunds.password, (errUnlock) => { devFunds.unlockAccounts(devFunds.password, (errUnlock) => {
assert.equal(errUnlock, null); assert.equal(errUnlock, null);
@ -92,10 +99,14 @@ describe('embark.DevFunds', function () {
it('should fund accounts', function (done) { it('should fund accounts', function (done) {
provider.injectResult('1234567890'); // account #1 balance if (devFunds.accounts.length === 0) {
provider.injectResult('1234567890'); // account #2 balance assert.equal(true, true, "no accounts to fund");
// provider.injectResult('0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe'); // send tx #1 return done();
// provider.injectResult('0x22F4d0A3C12E86b4b5F39B213f7e19D048276DAb'); // send tx #2 }
devFunds.accounts.forEach(_acct => {
provider.injectResult('1234567890'); // account balance
// provider.injectResult('0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe'); // send tx response
});
devFunds.fundAccounts(devFunds.balance, (errFundAccounts) => { devFunds.fundAccounts(devFunds.balance, (errFundAccounts) => {

View File

@ -1,10 +1,7 @@
var assert = require('assert'); const assert = require('assert');
var _ = require('lodash'); const _ = require('lodash');
const FakeIpcProvider = function IpcProvider() {
var FakeIpcProvider = function IpcProvider() {
var _this = this; var _this = this;
this.countId = 1; this.countId = 1;
this.notificationCount = 1; this.notificationCount = 1;
@ -32,7 +29,6 @@ var FakeIpcProvider = function IpcProvider() {
this.notificationCallbacks = []; this.notificationCallbacks = [];
}; };
FakeIpcProvider.prototype.send = function (payload, callback) { FakeIpcProvider.prototype.send = function (payload, callback) {
var _this = this; var _this = this;
@ -106,8 +102,6 @@ FakeIpcProvider.prototype.injectNotification = function (notification) {
// this.response = response; // this.response = response;
// }; // };
FakeIpcProvider.prototype.injectBatchResults = function (results, error) { FakeIpcProvider.prototype.injectBatchResults = function (results, error) {
var _this = this; var _this = this;
this.response.push(results.map(function (r) { this.response.push(results.map(function (r) {