Merge pull request #73 from sc-forks/signing-test

Add testrpc-sc signing test and lint
pull/76/head
c-g-e-w-e-k-e- 7 years ago committed by GitHub
commit ebda87dd3c
  1. 2
      .eslintrc
  2. 1
      bin/exec.js
  3. 19
      lib/app.js
  4. 2
      lib/instrumenter.js
  5. 2
      lib/truffleConfig.js
  6. 17
      test/app.js
  7. 31
      test/cli/sign.js
  8. 4
      test/conditional.js
  9. 6
      test/statements.js
  10. 22
      test/util/mockTestCommand.js

@ -14,7 +14,7 @@
/* General */
"consistent-return": [0],
"no-return-assign": [0],
"complexity": ["error", 6],
"complexity": ["error", 20],
"eol-last": [0],
"eqeqeq": ["error", "smart"],
"max-len": ["error", 150, 2],

@ -2,6 +2,7 @@
const App = require('./../lib/app.js');
const reqCwd = require('req-cwd');
const death = require('death');
const log = console.log;
const config = reqCwd.silent('./.solcover.js') || {};

@ -20,12 +20,12 @@ class App {
// Options
this.network = ''; // Default truffle network execution flag
this.silence = ''; // Default log level: configurable by --silence
this.silence = ''; // Default log level passed to shell
this.log = console.log;
// Other
this.testrpcProcess; // ref to testrpc server we need to close on exit
this.events; // ref to string loaded from 'allFiredEvents'
this.testrpcProcess = null; // ref to testrpc server we need to close on exit
this.events = null; // ref to string array loaded from 'allFiredEvents'
this.testsErrored = null; // flag set to non-null if truffle tests error
this.coverage = new CoverageMap(); // initialize a coverage map
@ -51,7 +51,6 @@ class App {
* the coverage environment folder. Process exits(1) if try fails
*/
generateCoverageEnvironment() {
this.log('Generating coverage environment');
try {
@ -76,7 +75,7 @@ class App {
// No coverage network defaults to the dev network on port 8555, high gas / low price.
} else {
const trufflejs = defaultTruffleConfig(this.port, gasLimitHex, gasPriceHex)
const trufflejs = defaultTruffleConfig(this.port, gasLimitHex, gasPriceHex);
fs.writeFileSync(`${this.coverageDir}/truffle.js`, trufflejs);
}
} catch (err) {
@ -94,7 +93,6 @@ class App {
* + Add instrumentation info to the coverage map
*/
instrumentTarget() {
this.skipFiles = this.skipFiles.map(contract => `${this.coverageDir}/contracts/${contract}`);
this.skipFiles.push(`${this.coverageDir}/contracts/Migrations.sol`);
@ -128,7 +126,6 @@ class App {
*/
launchTestrpc() {
return new Promise((resolve, reject) => {
if (!this.norpc) {
const defaultRpcOptions = `--gasLimit ${gasLimitHex} --accounts ${this.accounts} --port ${this.port}`;
const options = this.testrpcOptions || defaultRpcOptions;
@ -153,7 +150,7 @@ class App {
} else {
return resolve();
}
})
});
}
/**
@ -163,9 +160,7 @@ class App {
* Also reads the 'allFiredEvents' log.
*/
runTestCommand() {
try {
const defaultCommand = `truffle test ${this.network} ${this.silence}`;
const command = this.testCommand || defaultCommand;
this.log(`Running: ${command}\n(this can take a few seconds)...`);
@ -197,7 +192,6 @@ class App {
* Generate coverage / write coverage report / run istanbul
*/
generateReport() {
const collector = new istanbul.Collector();
const reporter = new istanbul.Reporter();
@ -220,9 +214,8 @@ class App {
} catch (err) {
const msg = 'There was a problem generating the coverage map / running Istanbul.\n';
this.cleanUp(msg + err);
}
})
});
}
// ------------------------------------------ Utils ----------------------------------------------

@ -16,7 +16,7 @@ instrumenter.prePosition = function prePosition(expression){
expression.left.type === 'MemberExpression') {
expression.start -= 2;
}
}
};
instrumenter.instrumentAssignmentExpression = function instrumentAssignmentExpression(contract, expression) {
// The only time we instrument an assignment expression is if there's a conditional expression on

@ -10,5 +10,5 @@ module.exports = function truffleConfig(port, gasLimit, gasPrice) {
gasPrice: ${gasPrice}
}
}
};`
};`;
};

@ -27,9 +27,15 @@ describe('app', () => {
norpc: true,
};
before(() => {
before(done => {
const command = `./node_modules/.bin/testrpc-sc --gasLimit 0xfffffffffff --port ${port}`;
testrpcProcess = childprocess.exec(command);
testrpcProcess.stdout.on('data', data => {
if (data.includes('Listening')) {
done();
}
});
});
afterEach(() => {
@ -198,6 +204,14 @@ describe('app', () => {
collectGarbage();
});
it('testrpc-sc signs and recovers messages correctly', () => {
// sign.js signs and recovers
mock.install('Simple.sol', 'sign.js', config);
shell.exec(script);
assert(shell.error() === null, 'script should not error');
collectGarbage();
});
it('tests require assets outside of test folder: should generate coverage, cleanup & exit(0)', () => {
// Directory should be clean
assert(pathExists('./coverage') === false, 'should start without: coverage');
@ -239,6 +253,7 @@ describe('app', () => {
collectGarbage();
});
it('contract uses inheritance: should generate coverage, cleanup & exit(0)', () => {
// Run against a contract that 'is' another contract
assert(pathExists('./coverage') === false, 'should start without: coverage');

@ -0,0 +1,31 @@
/* eslint-env node, mocha */
/* global artifacts, contract, assert */
const Web3 = require('web3');
const ethUtil = require('ethereumjs-util');
const provider = new Web3.providers.HttpProvider('http://localhost:8555'); // testrpc-sc
const web3 = new Web3(provider);
const Simple = artifacts.require('./Simple.sol');
contract('Simple', accounts => {
it('should set x to 5', () => {
let simple;
return Simple.deployed()
.then(instance => instance.test(5)) // We need this line to generate some coverage
.then(() => {
const message = 'Enclosed is my formal application for permanent residency in New Zealand';
const messageSha3 = web3.sha3(message);
const signature = web3.eth.sign(accounts[0], messageSha3);
const messageBuffer = new Buffer(messageSha3.replace('0x', ''), 'hex');
const messagePersonalHash = ethUtil.hashPersonalMessage(messageBuffer);
const sigParams = ethUtil.fromRpcSig(signature);
const publicKey = ethUtil.ecrecover(messagePersonalHash, sigParams.v, sigParams.r, sigParams.s);
const senderBuffer = ethUtil.pubToAddress(publicKey);
const sender = ethUtil.bufferToHex(senderBuffer);
assert.equal(sender, accounts[0]);
});
});
});

@ -168,13 +168,13 @@ describe('conditional statements', () => {
vm.execute(info.contract, 'a', []).then(events => {
const mapping = coverage.generate(events, pathPrefix);
assert.deepEqual(mapping[filePath].l, {
'11': 1, '12': 1,
11: 1, 12: 1,
});
assert.deepEqual(mapping[filePath].b, {
1: [0, 1],
});
assert.deepEqual(mapping[filePath].s, {
'1': 1, '2': 1,
1: 1, 2: 1,
});
assert.deepEqual(mapping[filePath].f, {
1: 1,

@ -109,14 +109,14 @@ describe('generic statements', () => {
vm.execute(info.contract, 'a', []).then(events => {
const mapping = coverage.generate(events, pathPrefix);
assert.deepEqual(mapping[filePath].l, {
6: 1, 10: 1, 11: 1
6: 1, 10: 1, 11: 1,
});
assert.deepEqual(mapping[filePath].b, {});
assert.deepEqual(mapping[filePath].s, {
1: 1, 2: 1, 3: 1
1: 1, 2: 1, 3: 1,
});
assert.deepEqual(mapping[filePath].f, {
1: 1, 2: 1
1: 1, 2: 1,
});
done();
}).catch(done);

@ -1,22 +1,22 @@
#!/usr/bin/env node
const fs = require('fs')
const request = require('request')
const fs = require('fs');
const request = require('request');
request({
uri: 'http://localhost:8888',
body: {
jsonrpc: "2.0",
method: "web3_clientVersion",
jsonrpc: '2.0',
method: 'web3_clientVersion',
params: [],
id: 0
id: 0,
},
json: true
json: true,
}, (error, response, body) => {
if (error) {
console.error(error)
process.exit(1)
console.error(error);
process.exit(1);
}
fs.writeFileSync('../allFiredEvents', 'foobar')
process.exit(0)
})
fs.writeFileSync('../allFiredEvents', 'foobar');
process.exit(0);
});

Loading…
Cancel
Save