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) {
let devFunds = new DevFunds({blockchainConfig: this.config});
devFunds.createFundAndUnlockAccounts((err) => {
cb(err);
DevFunds.new({blockchainConfig: this.config}).then(devFunds => {
devFunds.createFundAndUnlockAccounts((err) => {
cb(err);
});
});
};

View File

@ -18,6 +18,20 @@ class DevFunds {
}
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() {
if (this.networkId !== 1337) {
@ -27,7 +41,7 @@ class DevFunds {
}
// trigger regular txs due to a bug in geth and stuck transactions in --dev mode
regularTxs(cb) {
_regularTxs(cb) {
const self = this;
self.web3.eth.net.getId().then((networkId) => {
self.networkId = networkId;
@ -42,21 +56,11 @@ class DevFunds {
});
}
regularUnlocks() {
_regularUnlocks() {
const self = this;
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) {
const numAccountsToCreate = numAccounts - (this.accounts.length + 1);
if (numAccountsToCreate === 0) return cb();
@ -95,9 +99,6 @@ class DevFunds {
return cb();
}
async.waterfall([
(next) => {
this.getCurrentAccounts(next);
},
(next) => {
this.createAccounts(this.numAccounts, this.password, next);
},
@ -105,8 +106,8 @@ class DevFunds {
this.unlockAccounts(this.password, next);
},
(next) => {
this.regularTxs();
this.regularUnlocks();
this._regularTxs();
this._regularUnlocks();
this.fundAccounts(this.balance, next);
}
], cb);

View File

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

View File

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