diff --git a/lib/tests/run_tests.js b/lib/tests/run_tests.js index 17db45c2..a4e9d258 100644 --- a/lib/tests/run_tests.js +++ b/lib/tests/run_tests.js @@ -93,7 +93,6 @@ module.exports = { return Mocha.describe(describeName, callback); }; - console.info('Compiling contracts'.cyan); test.init((err) => { next(err, files); }); @@ -111,11 +110,13 @@ module.exports = { mocha.suite.timeout(0); mocha.suite.beforeAll('Wait for deploy', (done) => { + if (global.embark.needConfig) { + global.config({}); + } global.embark.onReady((err) => { done(err); }); }); - mocha.run(function (fails) { failures += fails; mocha.suite.removeAllListeners(); diff --git a/lib/tests/test.js b/lib/tests/test.js index a23ec66d..ee1fb521 100644 --- a/lib/tests/test.js +++ b/lib/tests/test.js @@ -34,14 +34,15 @@ class Test { constructor(options) { this.options = options || {}; this.simOptions = {}; - this.contracts = {}; this.events = new Events(); this.ready = true; + this.firstRunConfig = true; this.error = false; + this.contracts = {}; this.builtContracts = {}; this.compiledContracts = {}; this.logsSubscription = null; - + this.needConfig = true; this.web3 = new Web3(); } @@ -50,6 +51,16 @@ class Test { if (this.provider) { this.provider.stop(); } + + if (this.simOptions.accounts) { + this.simOptions.accounts = this.simOptions.accounts.map((account) => { + if (!account.hexBalance) { + account.hexBalance = '0x8AC7230489E80000'; // 10 ether + } + return {balance: account.hexBalance, secretKey: account.privateKey}; + }); + } + if (this.simOptions.host) { let {host, port, type, protocol, accounts} = this.simOptions; if (!protocol) { @@ -78,20 +89,11 @@ class Test { if (err) { return callback(err); } - self.subscribeToPendingTransactions(); callback(); }); }); } - if (this.simOptions.accounts) { - this.simOptions.accounts = this.simOptions.accounts.map((account) => { - if (!account.hexBalance) { - account.hexBalance = '0x8AC7230489E80000'; // 10 ether - } - return {balance: account.hexBalance, secretKey: account.privateKey}; - }); - } if (!this.sim) { this.sim = getSimulator(); } @@ -124,8 +126,6 @@ class Test { } init(callback) { - const self = this; - this.engine = new Engine({ env: this.options.env || 'test', // TODO: config will need to detect if this is a obj @@ -133,37 +133,23 @@ class Test { interceptLogs: false }); - this.initWeb3Provider((err) => { - if (err) { - return callback(err); - } - - this.engine.init({ - logger: new TestLogger({logLevel: this.options.loglevel}) - }); - - this.versions_default = this.engine.config.contractsConfig.versions; - // Reset contract config to nothing to make sure we deploy only what we want - this.engine.config.contractsConfig = { - contracts: {}, - versions: this.versions_default - }; - - this.engine.startService("libraryManager"); - this.engine.startService("codeRunner"); - this.initDeployServices(); - this.engine.startService("codeGenerator"); - - this.engine.contractsManager.build(() => { - self.builtContracts = cloneDeep(self.engine.contractsManager.contracts); - let className; - for (className in self.builtContracts) { - self.builtContracts[className].dependencyCount = null; - } - self.compiledContracts = cloneDeep(self.engine.contractsManager.compiledContracts); - callback(); - }); + this.engine.init({ + logger: new TestLogger({logLevel: this.options.loglevel}) }); + + this.versions_default = this.engine.config.contractsConfig.versions; + // Reset contract config to nothing to make sure we deploy only what we want + this.engine.config.contractsConfig = { + contracts: {}, + versions: this.versions_default + }; + + this.engine.startService("libraryManager"); + this.engine.startService("codeRunner"); + this.initDeployServices(); + this.engine.startService("codeGenerator"); + + callback(); } onReady(callback) { @@ -193,38 +179,37 @@ class Test { checkDeploymentOptions(options, callback) { const self = this; - if (!options.deployment) { - if (!self.simOptions.host && !self.simOptions.accounts) { - return callback(); - } - self.simOptions = {}; - } else { - self.simOptions = {}; - let resetServices = false; - if (options.deployment.accounts) { - // Account setup - self.simOptions.accounts = AccountParser.parseAccountsConfig(options.deployment.accounts, self.web3); - resetServices = true; - } - if (options.deployment.host && options.deployment.port && options.deployment.type) { - if (options.deployment.type !== 'rpc' && options.deployment.type !== 'ws') { - callback(__("contracts config error: unknown deployment type %s", options.deployment.type)); - } - Object.assign(self.simOptions, { - host: options.deployment.host, - port: options.deployment.port, - type: options.deployment.type - }); - resetServices = true; - } - if (!resetServices) { - return callback(); - } + let resetServices = false; + const {host, port, type, accounts} = options.deployment || {}; + + if (host && port && !['rpc', 'ws'].includes(type)) { + callback(__("contracts config error: unknown deployment type %s", type)); } + + if(accounts || port !== this.simOptions.port || type !== this.simOptions.type || host !== this.simOptions.host) { + resetServices = true; + } + if (accounts) { + self.simOptions.accounts = AccountParser.parseAccountsConfig(accounts, self.web3); + } else { + self.simOptions.account = null; + } + + Object.assign(self.simOptions, { + host, + port, + type + }); + + if (!resetServices && !self.firstRunConfig) { + return callback(); + } + self.initWeb3Provider((err) => { if (err) { return callback(err); } + self.firstRunConfig = false; self.initDeployServices(); callback(); }); @@ -232,6 +217,7 @@ class Test { config(options, callback) { const self = this; + self.needConfig = false; if (typeof (options) === 'function') { callback = options; options = {}; @@ -249,6 +235,21 @@ class Test { function checkDeploymentOpts(next) { self.checkDeploymentOptions(options, next); }, + function compileContracts(next) { + if (Object.keys(self.builtContracts).length > 0) { + return next(); + } + console.info('Compiling contracts'.cyan); + self.engine.contractsManager.build(() => { + self.builtContracts = cloneDeep(self.engine.contractsManager.contracts); + let className; + for (className in self.builtContracts) { + self.builtContracts[className].dependencyCount = null; + } + self.compiledContracts = cloneDeep(self.engine.contractsManager.compiledContracts); + next(); + }); + }, function resetContracts(next) { self.engine.contractsManager.contracts = cloneDeep(self.builtContracts); self.engine.contractsManager.compiledContracts = cloneDeep(self.compiledContracts); @@ -312,27 +313,27 @@ class Test { function createContractObject(accounts, next) { async.each(Object.keys(self.engine.contractsManager.contracts), (contractName, eachCb) => { const contract = self.engine.contractsManager.contracts[contractName]; - let data; if (!self.contracts[contractName]) { self.contracts[contractName] = {}; - data = ""; - } else { - data = self.contracts[contractName].options.data; } - Object.assign(self.contracts[contractName], new EmbarkJS.Contract({ + + let newContract = new EmbarkJS.Contract({ abi: contract.abiDefinition, address: contract.deployedAddress, from: self.web3.eth.defaultAccount, gas: 6000000, web3: self.web3 - })); + }); - self.contracts[contractName].address = contract.deployedAddress; - if (self.contracts[contractName].options) { - self.contracts[contractName].options.from = self.contracts[contractName].options.from || self.web3.eth.defaultAccount; - self.contracts[contractName].options.data = data; - self.contracts[contractName].options.gas = 6000000; + if (newContract.options) { + newContract.options.from = self.web3.eth.defaultAccount; + newContract.options.data = contract.code; + newContract.options.gas = 6000000; } + + Object.setPrototypeOf(self.contracts[contractName], newContract); + Object.assign(self.contracts[contractName], newContract); + eachCb(); }, (err) => { next(err, accounts); @@ -347,48 +348,20 @@ class Test { }); } - require(module) { - if (module.startsWith('Embark/contracts/')) { - const contractName = module.substr(17); - if (this.contracts[contractName]) { - return this.contracts[contractName]; - } - let contract = this.engine.contractsManager.contracts[contractName]; - if (!contract) { - const contractNames = Object.keys(this.engine.contractsManager.contracts); - // It is probably an instanceof - contractNames.find(contrName => { - // Find a contract with a similar name - if (contractName.indexOf(contrName) > -1) { - contract = this.engine.contractsManager.contracts[contrName]; - return true; - } - return false; - }); - // If still nothing, assign bogus one, we will redefine it anyway on deploy - if (!contract) { - console.warn(__('Could not recognize the contract name "%s"', contractName)); - console.warn(__('If it is an instance of another contract, it will be reassigned on deploy')); - console.warn(__('Otherwise, you can rename the contract to contain the parent contract in the name eg: Token2 for Token')); - contract = this.engine.contractsManager.contracts[contractNames[0]]; - } - } - this.contracts[contractName] = new EmbarkJS.Contract({ - abi: contract.abiDefinition, - address: contract.address, - from: this.web3.eth.defaultAccount, - gas: 6000000, - web3: this.web3 - }); - this.contracts[contractName].address = contract.address; - this.contracts[contractName].options.data = contract.code; - this.contracts[contractName].options.gas = 6000000; - this.web3.eth.getAccounts().then((accounts) => { - this.contracts[contractName].options.from = contract.from || accounts[0]; - }); - return this.contracts[contractName]; + require(path) { + const prefix = 'Embark/contracts/'; + if (!path.startsWith(prefix)) { + throw new Error(__('Unknown module %s', path)); } - throw new Error(__('Unknown module %s', module)); + let contractName = path.replace(prefix, ""); + let contract = this.contracts[contractName]; + if (contract) { + return contract; + } + + let newContract = {}; + this.contracts[contractName] = newContract; + return newContract; } }