Merge pull request #58 from cgewecke/truffle3-adriamb

Resolve inheritance issues
pull/1/head
c-g-e-w-e-k-e- 8 years ago committed by GitHub
commit 3fd5e32700
  1. 1
      .eslintignore
  2. 1
      .eslintrc
  3. 1
      .gitignore
  4. 1
      circle.yml
  5. 31
      coverageMap.js
  6. 73
      exec.js
  7. 18
      injector.js
  8. 6
      instrumentSolidity.js
  9. 8
      package.json
  10. 6
      test/conditional.js
  11. 4
      test/expressions.js
  12. 1
      test/if.js
  13. 1
      test/loops.js
  14. 25
      test/run.js
  15. 5
      test/run/block-gas-limit.js
  16. 4
      test/run/empty.js
  17. 18
      test/run/inheritance.js
  18. 18
      test/run/only-call.js
  19. 6
      test/run/simple.js
  20. 7
      test/run/sol-parse-fail.js
  21. 5
      test/run/truffle-crash.js
  22. 7
      test/run/truffle-test-fail.js
  23. 25
      test/util/mockTruffle.js
  24. 4
      test/util/util.js
  25. 7
      test/util/vm.js

@ -0,0 +1 @@
test/run/truffle-crash.js

@ -40,7 +40,6 @@
"semi": [2, "always"],
"no-unused-vars": 0,
"import/extensions": [0],
"import/no-dynamic-require": [0],
"arrow-parens":[2, "as-needed"],
"no-plusplus":[2, { "allowForLoopAfterthoughts": true }],
"no-bitwise": [2],

1
.gitignore vendored

@ -3,3 +3,4 @@ coverage.json
coverage/
node_modules/
.changelog
.DS_Store

@ -3,6 +3,7 @@ machine:
version: 6.9.1
dependencies:
pre:
- npm install -g truffle
- rm -rf node_modules/
test:
override:

@ -5,11 +5,7 @@
*/
const SolidityCoder = require('web3/lib/solidity/coder.js');
const path = require('path');
const lineTopic = 'b8995a65f405d9756b41a334f38d8ff0c93c4934e170d3c1429c3e7ca101014d';
const functionTopic = 'd4ce765fd23c5cc3660249353d61ecd18ca60549dd62cb9ca350a4244de7b87f';
const branchTopic = 'd4cf56ed5ba572684f02f889f12ac42d9583c8e3097802060e949bfbb3c1bff5';
const statementTopic = 'b51abbff580b3a34bbc725f2dc6f736e9d4b45a41293fd0084ad865a31fde0c8';
const keccak = require('keccakjs');
/**
* Converts solcover event data into an object that can be
@ -20,6 +16,10 @@ module.exports = class CoverageMap {
constructor() {
this.coverage = {};
this.lineTopics = [];
this.functionTopics = [];
this.branchTopics = [];
this.statementTopics = [];
}
/**
@ -29,6 +29,7 @@ module.exports = class CoverageMap {
* @param {String} canonicalContractPath target file location
* @return {Object} coverage map with all values set to zero
*/
addContract(info, canonicalContractPath) {
this.coverage[canonicalContractPath] = {
l: {},
@ -56,6 +57,17 @@ module.exports = class CoverageMap {
for (let x = 1; x <= Object.keys(info.statementMap).length; x++) {
this.coverage[canonicalContractPath].s[x] = 0;
}
const keccakhex = (x => {
const hash = new keccak(256); // eslint-disable-line new-cap
hash.update(x);
return hash.digest('hex');
});
this.lineTopics.push(keccakhex('__Coverage' + info.contractName + '(string,uint256)'));
this.functionTopics.push(keccakhex('__FunctionCoverage' + info.contractName + '(string,uint256)'));
this.branchTopics.push(keccakhex('__BranchCoverage' + info.contractName + '(string,uint256,uint256)'));
this.statementTopics.push(keccakhex('__StatementCoverage' + info.contractName + '(string,uint256)'));
}
/**
@ -68,19 +80,20 @@ module.exports = class CoverageMap {
generate(events, pathPrefix) {
for (let idx = 0; idx < events.length; idx++) {
const event = JSON.parse(events[idx]);
if (event.topics.indexOf(lineTopic) >= 0) {
if (event.topics.filter(t => this.lineTopics.indexOf(t) >= 0).length > 0) {
const data = SolidityCoder.decodeParams(['string', 'uint256'], event.data.replace('0x', ''));
const canonicalContractPath = data[0];
this.coverage[canonicalContractPath].l[data[1].toNumber()] += 1;
} else if (event.topics.indexOf(functionTopic) >= 0) {
} else if (event.topics.filter(t => this.functionTopics.indexOf(t) >= 0).length > 0) {
const data = SolidityCoder.decodeParams(['string', 'uint256'], event.data.replace('0x', ''));
const canonicalContractPath = data[0];
this.coverage[canonicalContractPath].f[data[1].toNumber()] += 1;
} else if (event.topics.indexOf(branchTopic) >= 0) {
} else if (event.topics.filter(t => this.branchTopics.indexOf(t) >= 0).length > 0) {
const data = SolidityCoder.decodeParams(['string', 'uint256', 'uint256'], event.data.replace('0x', ''));
const canonicalContractPath = data[0];
this.coverage[canonicalContractPath].b[data[1].toNumber()][data[2].toNumber()] += 1;
} else if (event.topics.indexOf(statementTopic) >= 0) {
} else if (event.topics.filter(t => this.statementTopics.indexOf(t) >= 0).length > 0) {
const data = SolidityCoder.decodeParams(['string', 'uint256'], event.data.replace('0x', ''));
const canonicalContractPath = data[0];
this.coverage[canonicalContractPath].s[data[1].toNumber()] += 1;

@ -7,11 +7,11 @@ const path = require('path');
const childprocess = require('child_process');
const getInstrumentedVersion = require('./instrumentSolidity.js');
const CoverageMap = require('./coverageMap.js');
const istanbul = require('istanbul');
const istanbulCollector = new istanbul.Collector();
const istanbulReporter = new istanbul.Reporter();
// Very high gas block limits / contract deployment limits
const gasLimitString = '0xfffffffffff';
const gasLimitHex = 0xfffffffffff;
@ -30,8 +30,28 @@ let silence = ''; // Default log level: configurable b
let log = console.log; // Default log level: configurable by --silence
let testrpcProcess; // ref to testrpc server we need to close on exit
let events; // ref to string loaded from 'allFiredEvents'
let events; // ref to string loaded from 'allFiredEvents'
// --------------------------------------- Utilities -----------------------------------------------
/**
* Removes coverage build artifacts, kills testrpc.
* Exits (1) and prints msg on error, exits (0) otherwise.
* @param {String} err error message
*/
function cleanUp(err) {
log('Cleaning up...');
shell.config.silent = true;
shell.rm('-Rf', `${coverageDir}`);
shell.rm('./allFiredEvents');
if (testrpcProcess) { testrpcProcess.kill(); }
if (err) {
log(`${err}\nExiting without generating coverage...`);
process.exit(1);
} else {
process.exit(0);
}
}
// --------------------------------------- Script --------------------------------------------------
const config = reqCwd.silent(`${workingDir}/.solcover.js`) || {};
@ -48,7 +68,7 @@ if (config.silent) {
if (!config.norpc) {
try {
log(`Launching testrpc on port ${port}`);
const command = `./node_modules/ethereumjs-testrpc-sc/bin/testrpc`;
const command = './node_modules/ethereumjs-testrpc-sc/bin/testrpc';
const options = `--gasLimit ${gasLimitString} --port ${port}`;
testrpcProcess = childprocess.exec(command + options);
} catch (err) {
@ -69,19 +89,19 @@ try {
const truffleConfig = reqCwd(`${workingDir}/truffle.js`);
// Coverage network opts specified: copy truffle.js whole to coverage environment
if (truffleConfig.networks.coverage){
if (truffleConfig.networks.coverage) {
shell.cp(`${workingDir}/truffle.js`, `${coverageDir}/truffle.js`);
// Coverage network opts NOT specified: default to the development network w/ modified
// port, gasLimit, gasPrice. Export the config object only.
} else {
} else {
truffleConfig.networks.development.port = port;
truffleConfig.networks.development.gas = gasLimitHex;
truffleConfig.networks.development.gasPrice = gasPriceHex;
coverageOption = '';
fs.writeFileSync(`${coverageDir}/truffle.js`, `module.exports = ${JSON.stringify(truffleConfig)}`);
}
} catch (err){
} catch (err) {
const msg = ('There was a problem generating the coverage environment: ');
cleanUp(msg + err);
}
@ -99,7 +119,7 @@ try {
if (file !== migrations) {
log('Instrumenting ', file);
const contractPath = path.resolve(file);
const canonicalPath = contractPath.split(`/coverageEnv`).join('');
const canonicalPath = contractPath.split('/coverageEnv').join('');
const contract = fs.readFileSync(contractPath).toString();
const instrumentedContractInfo = getInstrumentedVersion(contract, canonicalPath);
fs.writeFileSync(contractPath, instrumentedContractInfo.contract);
@ -114,9 +134,7 @@ try {
// coverage environment folder
try {
log('Launching Truffle (this can take a few seconds)...');
const truffle = `./../node_modules/truffle/cli.js`;
const command = `cd coverageEnv && ${truffle} test ${coverageOption} ${silence}`;
//const command = `cd coverageEnv && truffle test ${coverageOption} ${silence}`;
const command = `cd coverageEnv && truffle test ${coverageOption} ${silence}`;
shell.exec(command);
} catch (err) {
cleanUp(err);
@ -139,9 +157,9 @@ try {
// Generate coverage / write coverage report / run istanbul
try {
//coverage.generate(events, `${coverageDir}/contracts/`);
// coverage.generate(events, `${coverageDir}/contracts/`);
coverage.generate(events, './contracts');
const json = JSON.stringify(coverage.coverage);
fs.writeFileSync('./coverage.json', json);
@ -150,39 +168,16 @@ try {
istanbulReporter.add('lcov');
istanbulReporter.add('text');
istanbulReporter.write(istanbulCollector, true, () => {
log('Istanbul coverage reports generated');
log('Istanbul coverage reports generated');
});
} catch (err) {
if (config.testing){
cleanUp()
if (config.testing) {
cleanUp();
} else {
const msg = 'There was a problem generating producing the coverage map / running Istanbul.\n';
cleanUp(msg + err);
}
}
// Finish
cleanUp();
// --------------------------------------- Utilities -----------------------------------------------
/**
* Removes coverage build artifacts, kills testrpc.
* Exits (1) and prints msg on error, exits (0) otherwise.
* @param {String} err error message
*/
function cleanUp(err) {
log('Cleaning up...');
shell.config.silent = true;
shell.rm('-Rf', `${coverageDir}`);
shell.rm('./allFiredEvents');
if (testrpcProcess) { testrpcProcess.kill(); }
if (err) {
log(`${err}\nExiting without generating coverage...`);
process.exit(1);
} else {
process.exit(0);
}
}

@ -6,27 +6,27 @@ injector.callEvent = function injectCallEvent(contract, fileName, injectionPoint
const linecount = (contract.instrumented.slice(0, injectionPoint).match(/\n/g) || []).length + 1;
contract.runnableLines.push(linecount);
contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
'Coverage(\'' + fileName + '\',' + linecount + ');\n' +
'__Coverage' + contract.contractName + '(\'' + fileName + '\',' + linecount + ');\n' +
contract.instrumented.slice(injectionPoint);
};
injector.callFunctionEvent = function injectCallFunctionEvent(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
'FunctionCoverage(\'' + fileName + '\',' + injection.fnId + ');\n' +
'__FunctionCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.fnId + ');\n' +
contract.instrumented.slice(injectionPoint);
};
injector.callBranchEvent = function injectCallFunctionEvent(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
(injection.openBracket ? '{' : '') +
'BranchCoverage(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ')' +
'__BranchCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ')' +
(injection.comma ? ',' : ';') +
contract.instrumented.slice(injectionPoint);
};
injector.callEmptyBranchEvent = function injectCallEmptyBranchEvent(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
'else { BranchCoverage(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ');}\n' +
'else { __BranchCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.branchId + ',' + injection.locationIdx + ');}\n' +
contract.instrumented.slice(injectionPoint);
};
@ -44,16 +44,16 @@ injector.literal = function injectLiteral(contract, fileName, injectionPoint, in
injector.statement = function injectStatement(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
' StatementCoverage(\'' + fileName + '\',' + injection.statementId + ');\n' +
' __StatementCoverage' + contract.contractName + '(\'' + fileName + '\',' + injection.statementId + ');\n' +
contract.instrumented.slice(injectionPoint);
};
injector.eventDefinition = function injectEventDefinition(contract, fileName, injectionPoint, injection) {
contract.instrumented = contract.instrumented.slice(0, injectionPoint) +
'event Coverage(string fileName, uint256 lineNumber);\n' +
'event FunctionCoverage(string fileName, uint256 fnId);\n' +
'event StatementCoverage(string fileName, uint256 statementId);\n' +
'event BranchCoverage(string fileName, uint256 branchId, uint256 locationIdx);\n' +
'event __Coverage' + contract.contractName + '(string fileName, uint256 lineNumber);\n' +
'event __FunctionCoverage' + contract.contractName + '(string fileName, uint256 fnId);\n' +
'event __StatementCoverage' + contract.contractName + '(string fileName, uint256 statementId);\n' +
'event __BranchCoverage' + contract.contractName + '(string fileName, uint256 branchId, uint256 locationIdx);\n' +
contract.instrumented.slice(injectionPoint);
};

@ -38,8 +38,12 @@ module.exports = function instrumentSolidity(contractSource, fileName) {
contract.preprocessed = preprocessor.run(contract.source);
contract.instrumented = contract.preprocessed;
ast = SolidityParser.parse(contract.preprocessed);
const contractStatement = ast.body.filter(node => node.type === 'ContractStatement');
contract.contractName = contractStatement[0].name;
parse[ast.type](contract, ast);
// var result = solparse.parse(contract);
@ -59,5 +63,7 @@ module.exports = function instrumentSolidity(contractSource, fileName) {
});
retValue.runnableLines = contract.runnableLines;
retValue.contract = contract.instrumented;
retValue.contractName = contractStatement[0].name;
return retValue;
};

@ -18,16 +18,16 @@
"commander": "^2.9.0",
"ethereumjs-testrpc": "https://github.com/sc-forks/testrpc-sc.git",
"istanbul": "^0.4.5",
"keccakjs": "^0.2.1",
"mkdirp": "^0.5.1",
"req-cwd": "^1.0.1",
"shelljs": "^0.7.4",
"sol-explore": "^1.6.2",
"solidity-parser": "0.3.0",
"truffle": "git+https://github.com/cgewecke/truffle.git"
"solidity-parser": "0.3.0"
},
"devDependencies": {
"crypto-js": "^3.1.9-1",
"eslint": "^3.13.1",
"eslint": "^3.19.0",
"eslint-config-airbnb-base": "^11.0.1",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-mocha": "^4.8.0",
@ -37,6 +37,6 @@
"istanbul": "^0.4.5",
"merkle-patricia-tree": "~2.1.2",
"mocha": "^3.1.0",
"solc": "0.4.6"
"solc": "0.4.8"
}
}

@ -1,6 +1,5 @@
/* eslint-env node, mocha */
const solc = require('solc');
const path = require('path');
const getInstrumentedVersion = require('./../instrumentSolidity.js');
const util = require('./util/util.js');
@ -159,9 +158,10 @@ describe('conditional statements', () => {
});
// Solcover has trouble with this case. The conditional coverage strategy relies on being able to
// reference the left-hand variable before its value is assigned. Solidity doesn't allow this for 'var'.
// reference the left-hand variable before its value is assigned. Solidity doesn't allow this
// for 'var'.
/* it('should cover a variable delcaration assignment by conditional that reaches the alternate', (done) => {
/* it('should cover a var decl assignment by conditional that reaches the alternate', (done) => {
const contract = util.getCode('conditional/variable-decl-assignment-alternate.sol');
const info = getInstrumentedVersion(contract, filePath);
const coverage = new CoverageMap();

@ -3,10 +3,7 @@
const solc = require('solc');
const getInstrumentedVersion = require('./../instrumentSolidity.js');
const util = require('./util/util.js');
const CoverageMap = require('./../coverageMap');
const path = require('path');
const vm = require('./util/vm');
const assert = require('assert');
/**
* NB: passing '1' to solc as an option activates the optimiser
@ -15,7 +12,6 @@ const assert = require('assert');
*/
describe('generic expressions', () => {
const filePath = path.resolve('./test.sol');
const pathPrefix = './';
it('should compile after instrumenting a single binary expression', () => {
const contract = util.getCode('expressions/single-binary-expression.sol');

@ -1,6 +1,5 @@
/* eslint-env node, mocha */
const solc = require('solc');
const path = require('path');
const getInstrumentedVersion = require('./../instrumentSolidity.js');
const util = require('./util/util.js');

@ -1,6 +1,5 @@
/* eslint-env node, mocha */
const solc = require('solc');
const path = require('path');
const getInstrumentedVersion = require('./../instrumentSolidity.js');
const util = require('./util/util.js');

@ -1,3 +1,5 @@
/* eslint-env node, mocha */
const assert = require('assert');
const shell = require('shelljs');
const fs = require('fs');
@ -14,13 +16,12 @@ function collectGarbage() {
describe('run', () => {
let testrpcProcess = null;
let script = 'node ./exec.js'
let launchTestRpc = false;
let port = 8555;
const script = 'node ./exec.js';
const port = 8555;
config = {
dir: "./mock",
port: port,
const config = {
dir: './mock',
port,
testing: true,
silent: true, // <-- Set to false to debug tests
norpc: true,
@ -38,20 +39,20 @@ describe('run', () => {
after(() => {
mock.restoreCoverage();
//testrpcProcess.kill();
testrpcProcess.kill();
});
// This pre-test flushes the suite. There's some kind of sequencing issue here in development,
// This pre-test flushes the suite. There's some kind of sequencing issue here in development,
// possibly tied to the use of ethereumjs-vm in the coverage tests?
// - tests pass w/out this if we only run these test - e.g. it only fails when running the suite.
// - the first test always fails unless there is a fresh testrpc install.
// - the first test always fails unless there is a fresh testrpc install.
it('flush test suite', () => {
mock.install('Simple.sol', 'simple.js', config);
shell.exec(script); // <---- This fails mysteriously, but we don't test here.
collectGarbage();
});
// This test should be positioned first (or second if flushing) in the suite because of
// This test should be positioned first (or second if flushing) in the suite because of
// the way we're launching testrpc
it('simple contract: should generate coverage, cleanup & exit(0)', () => {
// Directory should be clean
@ -95,7 +96,7 @@ describe('run', () => {
});
it('contract uses inheritance: should generate coverage, cleanup & exit(0)', () => {
// Run against a contract that 'is' another contract
// Run against a contract that 'is' another contract
assert(pathExists('./coverage') === false, 'should start without: coverage');
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json');
mock.installInheritanceTest(config);
@ -109,7 +110,7 @@ describe('run', () => {
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8'));
const ownedPath = Object.keys(produced)[0];
const proxyPath = Object.keys(produced)[1];
assert(produced[ownedPath].fnMap['1'].name === 'Owned', 'coverage.json should map "Owned"');
assert(produced[proxyPath].fnMap['1'].name === 'isOwner', 'coverage.json should map "isOwner"');
collectGarbage();

@ -1,6 +1,7 @@
/* eslint-env node, mocha */
/* global artifacts, contract */
const Expensive = artifacts.require('./Expensive.sol');
contract('Expensive', accounts => {
contract('Expensive', () => {
it('should deploy', () => Expensive.deployed());
});

@ -1,6 +1,8 @@
/* eslint-env node, mocha */
/* global artifacts, contract */
const Empty = artifacts.require('./Empty.sol');
contract('Empty', accounts => {
contract('Empty', () => {
it('should deploy', () => Empty.deployed());
});

@ -1,12 +1,14 @@
/* eslint-env node, mocha */
/* global artifacts, contract, assert */
const Owned = artifacts.require('./Owned.sol');
const Proxy = artifacts.require('./Proxy.sol');
contract('Proxy', accounts => {
it('Should compile and run when one contract inherits from another', () => {
let proxy;
return Owned.deployed()
.then(instance => Proxy.deployed())
.then(instance => instance.isOwner.call({from: accounts[0]}))
.then(val => assert.equal(val, true));
});
});
it('Should compile and run when one contract inherits from another', () => Owned.deployed()
.then(() => Proxy.deployed())
.then(instance => instance.isOwner.call({
from: accounts[0],
}))
.then(val => assert.equal(val, true)));
});

@ -1,13 +1,17 @@
/* eslint-env node, mocha */
/* global artifacts, contract, assert */
const OnlyCall = artifacts.require('./OnlyCall.sol');
contract('OnlyCall', accounts => {
it('should return val + 2', function(done){
OnlyCall.deployed().then(function(instance){
instance.addTwo.call(5, {from: accounts[0]}).then(function(val){
assert.equal(val, 7);
done();
})
})
it('should return val + 2', done => {
OnlyCall.deployed().then(instance => {
instance.addTwo.call(5, {
from: accounts[0],
}).then(val => {
assert.equal(val, 7);
done();
});
});
});
});

@ -1,14 +1,16 @@
/* eslint-env node, mocha */
/* global artifacts, contract, assert */
const Simple = artifacts.require('./Simple.sol');
contract('Simple', accounts => {
contract('Simple', () => {
it('should set x to 5', () => {
let simple;
return Simple.deployed().then(instance => {
simple = instance;
return simple.test(5);
})
.then(val => simple.getX.call())
.then(() => simple.getX.call())
.then(val => assert.equal(val.toNumber(), 5));
});
});

@ -1,16 +1,17 @@
/* eslint-env node, mocha */
/* global artifacts, contract, assert */
const Simple = artifacts.require('./Simple.sol');
// This test is constructed correctly but the SimpleError.sol has a syntax error
contract('SimpleError', accounts => {
contract('SimpleError', () => {
it('should set x to 5', () => {
let simple;
return Simple.deployed().then(instance => {
simple = instance;
return simple.test(5);
})
.then(val => simple.getX.call())
.then(() => simple.getX.call())
.then(val => assert.equal(val, 5));
});
});

@ -1,9 +1,10 @@
'use strict'
/* eslint-env node, mocha */
/* global artifacts, contract */
var Simple = artifacts.require('./Simple.sol');
// This test should break truffle because it has a syntax error.
contract('Simple', function(accounts){
contract('Simple', () => {
it('should crash', function(){
return Simple.deployed().then.why.
})

@ -1,15 +1,16 @@
/* eslint-env node, mocha */
/* global artifacts, contract, assert */
const Simple = artifacts.require('./Simple.sol');
contract('Simple', accounts => {
contract('Simple', () => {
it('should set x to 5', () => {
let simple;
return Simple.deployed().then(instance => {
simple = instance;
return simple.test(5);
})
.then(val => simple.getX.call())
.then(() => simple.getX.call())
.then(val => assert.equal(val.toNumber(), 4)); // <-- Wrong result: test fails
});
});

@ -3,7 +3,6 @@
This file contains utilities for generating a mock truffle project to test solcover's
run script against.
*/
const assert = require('assert');
const fs = require('fs');
const shell = require('shelljs');
@ -11,7 +10,7 @@ const shell = require('shelljs');
* Moves existing coverage reports into a safe place while testing run script which
* would overwrite them. Silences shell complaints about non-existent files.
*/
module.exports.protectCoverage = function () {
module.exports.protectCoverage = function protectCoverage() {
shell.config.silent = true;
shell.rm('-Rf', './safe');
shell.mkdir('./safe');
@ -24,7 +23,7 @@ module.exports.protectCoverage = function () {
* Restores pre-existing coverage reports after testing run script.
* Silences shell complaints about non-existent files.
*/
module.exports.restoreCoverage = function () {
module.exports.restoreCoverage = function restoreCoverage() {
shell.config.silent = true;
shell.mv('./safe/coverage', './coverage');
shell.mv('./safe/coverage.json', './coverage.json');
@ -38,17 +37,17 @@ module.exports.restoreCoverage = function () {
* @param {String} contract <contractName.sol> located in /test/sources/run/
* @param {[type]} test <testName.js> located in /test/run/
*/
module.exports.install = function (contract, test, config) {
module.exports.install = function install(contract, test, config) {
shell.mkdir('./mock');
shell.mkdir('./mock/contracts');
shell.mkdir('./mock/migrations');
shell.mkdir('./mock/test');
// Mock contracts
if (Array.isArray(contract)){
if (Array.isArray(contract)) {
contract.forEach(item => {
shell.cp(`./test/sources/run/${item}`, `./mock/contracts/${item}`);
})
});
} else {
shell.cp(`./test/sources/run/${contract}`, `./mock/contracts/${contract}`);
}
@ -62,7 +61,7 @@ module.exports.install = function (contract, test, config) {
deployer.deploy(Migrations);
};`;
const contractLocation = './' + contract;
const contractLocation = `./${contract}`;
const deployContracts = `
var contract = artifacts.require('${contractLocation}');
module.exports = function(deployer) {
@ -97,15 +96,15 @@ module.exports.install = function (contract, test, config) {
* @param {String} contract <contractName.sol> located in /test/sources/run/
* @param {[type]} test <testName.js> located in /test/run/
*/
module.exports.installInheritanceTest = function (config) {
module.exports.installInheritanceTest = function installInheritanceTest(config) {
shell.mkdir('./mock');
shell.mkdir('./mock/contracts');
shell.mkdir('./mock/migrations');
shell.mkdir('./mock/test');
// Mock contracts
shell.cp(`./test/sources/run/Proxy.sol`, `./mock/contracts/Proxy.sol`);
shell.cp(`./test/sources/run/Owned.sol`, `./mock/contracts/Owned.sol`);
shell.cp('./test/sources/run/Proxy.sol', './mock/contracts/Proxy.sol');
shell.cp('./test/sources/run/Owned.sol', './mock/contracts/Owned.sol');
shell.cp('./test/sources/run/Migrations.sol', './mock/contracts/Migrations.sol');
// Mock migrations
@ -128,7 +127,7 @@ module.exports.installInheritanceTest = function (config) {
fs.writeFileSync('./mock/migrations/2_deploy_contracts.js', deployContracts);
// Mock test
shell.cp(`./test/run/inheritance.js`, `./mock/test/inheritance.js`);
shell.cp('./test/run/inheritance.js', './mock/test/inheritance.js');
// Mock truffle.js
const trufflejs = `module.exports = {
@ -149,11 +148,11 @@ module.exports.installInheritanceTest = function (config) {
/**
* Removes mock truffle project and coverage reports generated by runCovered tests
*/
module.exports.remove = function () {
module.exports.remove = function remove() {
shell.config.silent = true;
shell.rm('./.solcover.js');
shell.rm('-Rf', 'mock');
shell.rm('-Rf', 'coverage');
shell.rm('coverage.json');
shell.config.silent = false;
};
};

@ -7,11 +7,11 @@ const path = require('path');
* @return {String} contents of a .sol file
*/
module.exports.getCode = function getCode(_path) {
return fs.readFileSync(path.join(__dirname, './../sources/' + _path), 'utf8');
return fs.readFileSync(path.join(__dirname, `./../sources/${_path}`), 'utf8');
};
module.exports.report = function report(errors) {
if (errors) {
throw new Error('Instrumented solidity invalid: ' + errors);
throw new Error(`Instrumented solidity invalid: ${errors}`);
}
};

@ -1,5 +1,4 @@
const solc = require('solc');
const path = require('path');
const VM = require('ethereumjs-vm');
const Account = require('ethereumjs-account');
const Transaction = require('ethereumjs-tx');
@ -17,12 +16,12 @@ const accountAddress = new Buffer('7caf6f9bc8b3ba5c7824f934c826bd6dc38c8467', 'h
* Source: consensys/eth-lightwallet/lib/txutils.js (line 18)
*/
function encodeFunctionTxData(functionName, types, args) {
const fullName = functionName + '(' + types.join() + ')';
const fullName = `${functionName}(${types.join()})`;
const signature = CryptoJS.SHA3(fullName, {
outputLength: 256,
}).toString(CryptoJS.enc.Hex).slice(0, 8);
const dataHex = signature + coder.encodeParams(types, args);
return '0x' + dataHex;
return `0x${dataHex}`;
}
/**
@ -112,7 +111,7 @@ function callMethod(vm, abi, address, functionName, args) {
const tx = new Transaction(options);
tx.sign(new Buffer(secretKey, 'hex'));
return new Promise((resolve, reject) => {
return new Promise(resolve => {
vm.runTx({
tx,
}, (err, results) => {

Loading…
Cancel
Save