2018-10-04 11:40:41 +00:00
|
|
|
const Test = require('./test');
|
|
|
|
const async = require('async');
|
|
|
|
const fs = require('fs-extra');
|
|
|
|
const remixTests = require('remix-tests');
|
|
|
|
const Base = require('mocha/lib/reporters/base');
|
|
|
|
const color = Base.color;
|
|
|
|
|
|
|
|
class SolcTest extends Test {
|
|
|
|
constructor(options) {
|
|
|
|
super(options);
|
|
|
|
this.assertLibCode = remixTests.assertLibCode;
|
|
|
|
}
|
2018-10-18 12:37:28 +00:00
|
|
|
|
2018-10-04 11:40:41 +00:00
|
|
|
init(cb) {
|
|
|
|
const self = this;
|
|
|
|
super.init(() => {
|
2018-10-18 12:37:28 +00:00
|
|
|
self.events.request('config:contractsFiles:add', 'remix_tests.sol', (callback) => {
|
|
|
|
callback(self.assertLibCode);
|
|
|
|
});
|
2018-10-04 11:40:41 +00:00
|
|
|
cb();
|
|
|
|
});
|
|
|
|
}
|
2018-10-18 12:37:28 +00:00
|
|
|
|
2018-10-04 11:40:41 +00:00
|
|
|
setupTests(files, cb) {
|
|
|
|
const self = this;
|
|
|
|
|
|
|
|
async.waterfall([
|
2018-10-18 12:37:28 +00:00
|
|
|
function addContracts(next) {
|
|
|
|
files.forEach((file) => {
|
|
|
|
let testFile = self._prepareContractForTest(file);
|
|
|
|
self.events.request('config:contractsFiles:add', file, (callback) => {
|
|
|
|
callback(testFile);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
next();
|
|
|
|
},
|
2018-10-04 11:40:41 +00:00
|
|
|
function initWeb3Provider(next) {
|
|
|
|
self.initWeb3Provider(next);
|
|
|
|
},
|
|
|
|
function resetContracts(next) {
|
2018-10-18 12:37:28 +00:00
|
|
|
self.events.request("contracts:reset:dependencies", next);
|
2018-10-04 11:40:41 +00:00
|
|
|
},
|
|
|
|
function compile(next) {
|
|
|
|
console.info('Compiling contracts'.cyan);
|
2018-10-18 12:37:28 +00:00
|
|
|
self.events.request("contracts:build", false, next);
|
2018-10-04 11:40:41 +00:00
|
|
|
},
|
|
|
|
function determineContractsToDeploy(next) {
|
2018-10-18 12:37:28 +00:00
|
|
|
self.events.request("contracts:list", (err, contracts) => {
|
|
|
|
let contractsToDeploy = contracts.filter((contract) => {
|
|
|
|
return contract.filename && contract.filename.indexOf('_test.sol') >= 0;
|
|
|
|
});
|
2018-10-04 11:40:41 +00:00
|
|
|
let assertLib = contracts.filter((contract) => contract.filename === 'remix_tests.sol')[0];
|
|
|
|
next(null, [assertLib].concat(contractsToDeploy));
|
|
|
|
});
|
|
|
|
},
|
|
|
|
function deployContracts(contracts, next) {
|
|
|
|
console.info('Deploying contracts'.cyan);
|
|
|
|
let fns = [];
|
|
|
|
contracts.forEach((contract) => {
|
|
|
|
contract._gasLimit = self.gasLimit;
|
|
|
|
let fn = (cb) => {
|
2018-10-18 12:37:28 +00:00
|
|
|
self.events.request('deploy:contract', contract, cb);
|
2018-10-04 11:40:41 +00:00
|
|
|
};
|
|
|
|
fns.push(fn);
|
|
|
|
});
|
|
|
|
async.series(fns, next);
|
|
|
|
}
|
2018-10-18 12:37:28 +00:00
|
|
|
], cb);
|
2018-10-04 11:40:41 +00:00
|
|
|
}
|
2018-10-18 12:37:28 +00:00
|
|
|
|
2018-10-04 11:40:41 +00:00
|
|
|
runTests(file, cb) {
|
|
|
|
const self = this;
|
2018-10-18 12:37:28 +00:00
|
|
|
self.logger.info('Running tests'.cyan);
|
|
|
|
const forwardSlashFile = file.replace(/\\/g, '/');
|
|
|
|
|
|
|
|
async.waterfall([
|
|
|
|
function getContracts(next) {
|
|
|
|
self.events.request('contracts:all', (err, contracts) => {
|
|
|
|
if (err) {
|
|
|
|
return next(err);
|
|
|
|
}
|
|
|
|
const contractsToTest = [];
|
|
|
|
|
|
|
|
Object.keys(contracts).forEach((contract) => {
|
|
|
|
if (contracts[contract].filename &&
|
|
|
|
contracts[contract].filename.replace(/\\/g, '/') === forwardSlashFile) {
|
|
|
|
contractsToTest.push(contracts[contract]);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
next(null, contractsToTest);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
function getWeb3Object(contracts, next) {
|
|
|
|
self.events.request('blockchain:get', (web3) => {
|
|
|
|
next(null, contracts, web3);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
function run(contracts, web3, next) {
|
|
|
|
let fns = [];
|
|
|
|
contracts.forEach((contract) => {
|
|
|
|
let fn = (_callback) => {
|
|
|
|
// TODO: web3 is not injected into the function. Issue has been raised on remixTests.
|
|
|
|
// To fix once web3 has been made injectable.
|
|
|
|
remixTests.runTest(contract.className, Test.getWeb3Contract(contract, web3),
|
|
|
|
self._prettyPrint.bind(self), _callback);
|
|
|
|
};
|
|
|
|
fns.push(fn);
|
|
|
|
});
|
|
|
|
async.series(fns, next);
|
|
|
|
}
|
|
|
|
], cb);
|
2018-10-04 11:40:41 +00:00
|
|
|
}
|
2018-10-18 12:37:28 +00:00
|
|
|
|
2018-10-04 11:40:41 +00:00
|
|
|
// dynamically insert Assert library as an import
|
|
|
|
// regexIndexOf has been added to String's prototype in remix-tests module
|
|
|
|
_prepareContractForTest(file) {
|
|
|
|
let c = fs.readFileSync(file).toString();
|
|
|
|
const s = /^(import)\s['"](remix_tests.sol)['"];/gm;
|
|
|
|
if (c.regexIndexOf(s) < 0) {
|
|
|
|
c = c.replace(/(pragma solidity \^\d+\.\d+\.\d+;)/, '$1\nimport \"remix_tests.sol\";');
|
|
|
|
}
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
_prettyPrint(obj) {
|
|
|
|
if (obj.type === 'contract') {
|
2018-10-18 12:37:28 +00:00
|
|
|
this.logger.info(color('suite', '%s'), obj.value);
|
2018-10-04 11:40:41 +00:00
|
|
|
} else if(obj.type === 'testPass') {
|
|
|
|
let fmt = color('checkmark', ' ' + Base.symbols.ok) + color('pass', ' %s');
|
2018-10-18 12:37:28 +00:00
|
|
|
this.logger.info(fmt, obj.value);
|
2018-10-04 11:40:41 +00:00
|
|
|
} else if(obj.type === 'testFailure') {
|
|
|
|
let fmt = color('fail', ' %s %s');
|
2018-10-18 12:37:28 +00:00
|
|
|
this.logger.info(fmt, Base.symbols.err, obj.value);
|
2018-10-04 11:40:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = SolcTest;
|