|
|
@ -1,241 +1,85 @@ |
|
|
|
/* eslint-env node, mocha */ |
|
|
|
/* eslint-env node, mocha */ |
|
|
|
|
|
|
|
|
|
|
|
/*const assert = require('assert'); |
|
|
|
const assert = require('assert'); |
|
|
|
const shell = require('shelljs'); |
|
|
|
const shell = require('shelljs'); |
|
|
|
const fs = require('fs'); |
|
|
|
const fs = require('fs'); |
|
|
|
const childprocess = require('child_process'); |
|
|
|
const childprocess = require('child_process'); |
|
|
|
const mock = require('./util/mockTruffle.js'); |
|
|
|
const mock = require('../util/mockTruffle.js'); |
|
|
|
|
|
|
|
|
|
|
|
// shell.test alias for legibility
|
|
|
|
// shell.test alias for legibility
|
|
|
|
function pathExists(path) { return shell.test('-e', path); } |
|
|
|
function pathExists(path) { return shell.test('-e', path); } |
|
|
|
|
|
|
|
|
|
|
|
// tests run out of memory in CI without this
|
|
|
|
function assertCleanInitialState(){ |
|
|
|
function collectGarbage() { |
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
if (global.gc) { global.gc(); } |
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
describe('app', () => { |
|
|
|
function assertCoverageGenerated(){ |
|
|
|
let testrpcProcess = null; |
|
|
|
assert(pathExists('./coverage') === true, 'script should gen coverage folder'); |
|
|
|
const script = 'node ./bin/exec.js'; |
|
|
|
assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); |
|
|
|
const port = 8555; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const config = { |
|
|
|
|
|
|
|
dir: './mock', |
|
|
|
|
|
|
|
port, |
|
|
|
|
|
|
|
testing: true, |
|
|
|
|
|
|
|
silent: true, // <-- Set to false to debug tests
|
|
|
|
|
|
|
|
norpc: true, |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
before(done => { |
|
|
|
|
|
|
|
const command = `npx testrpc-sc --gasLimit 0xfffffffffff --port ${port}`; |
|
|
|
|
|
|
|
testrpcProcess = childprocess.exec(command); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
testrpcProcess.stdout.on('data', data => { |
|
|
|
|
|
|
|
if (data.includes('Listening')) { |
|
|
|
|
|
|
|
done(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
afterEach(() => { |
|
|
|
function assertCoverageNotGenerated(){ |
|
|
|
mock.remove(); |
|
|
|
assert(pathExists('./coverage') !== true, 'script should NOT gen coverage folder'); |
|
|
|
}); |
|
|
|
assert(pathExists('./coverage.json') !== true, 'script should NOT gen coverage.json'); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
after(() => { |
|
|
|
function assertExecutionSucceeds(){ |
|
|
|
testrpcProcess.kill(); |
|
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function assertExecutionFails(){ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
describe.skip('app', function() { |
|
|
|
|
|
|
|
afterEach(() => mock.remove()); |
|
|
|
|
|
|
|
|
|
|
|
// #1: The 'config' tests ask exec.js to run testrpc on special ports, the subsequent tests use
|
|
|
|
|
|
|
|
// the testrpc launched in the before() block. For some reason config tests fail randomly
|
|
|
|
|
|
|
|
// unless they are at the top of the suite. Hard to debug since they pass if logging is turned
|
|
|
|
|
|
|
|
// on - there might be a timing issue around resource cleanup or something.
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// #2: Creating repeated instances of testrpc hits the container memory limit on
|
|
|
|
|
|
|
|
// CI so these tests are disabled for that context
|
|
|
|
|
|
|
|
it('config with testrpc options string: should generate coverage, cleanup & exit(0)', () => { |
|
|
|
it('config with testrpc options string: should generate coverage, cleanup & exit(0)', () => { |
|
|
|
if (!process.env.CI) { |
|
|
|
|
|
|
|
const privateKey = '0x3af46c9ac38ee1f01b05f9915080133f644bf57443f504d339082cb5285ccae4'; |
|
|
|
|
|
|
|
const balance = '0xfffffffffffffff'; |
|
|
|
|
|
|
|
const testConfig = Object.assign({}, config); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
testConfig.testrpcOptions = `--account="${privateKey},${balance}" --port 8777`; |
|
|
|
|
|
|
|
testConfig.dir = './mock'; |
|
|
|
|
|
|
|
testConfig.norpc = false; |
|
|
|
|
|
|
|
testConfig.port = 8777; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Installed test will process.exit(1) and crash truffle if the test isn't
|
|
|
|
|
|
|
|
// loaded with the account specified above
|
|
|
|
|
|
|
|
mock.install('Simple.sol', 'testrpc-options.js', testConfig); |
|
|
|
|
|
|
|
shell.exec(script); |
|
|
|
|
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
|
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('config with test command options string: should run test', () => { |
|
|
|
const privateKey = '0x3af46c9ac38ee1f01b05f9915080133f644bf57443f504d339082cb5285ccae4'; |
|
|
|
if (!process.env.CI) { |
|
|
|
const balance = '0xfffffffffffffff'; |
|
|
|
assert(pathExists('./allFiredEvents') === false, 'should start without: events log'); |
|
|
|
const testConfig = Object.assign({}, config); |
|
|
|
const testConfig = Object.assign({}, config); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
testConfig.testCommand = 'mocha --timeout 5000'; |
|
|
|
|
|
|
|
testConfig.dir = './mock'; |
|
|
|
|
|
|
|
testConfig.norpc = false; |
|
|
|
|
|
|
|
testConfig.port = 8888; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Installed test will write a fake allFiredEvents to ./ after 4000ms
|
|
|
|
|
|
|
|
// allowing test to pass
|
|
|
|
|
|
|
|
mock.install('Simple.sol', 'command-options.js', testConfig); |
|
|
|
|
|
|
|
shell.exec(script); |
|
|
|
|
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
|
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('config racing test command: should run test after testrpc has started', () => { |
|
|
|
testConfig.testrpcOptions = `--account="${privateKey},${balance}" --port 8777`; |
|
|
|
if (!process.env.CI) { |
|
|
|
testConfig.dir = './mock'; |
|
|
|
assert(pathExists('./allFiredEvents') === false, 'should start without: events log'); |
|
|
|
testConfig.norpc = false; |
|
|
|
const testConfig = Object.assign({}, config); |
|
|
|
testConfig.port = 8777; |
|
|
|
|
|
|
|
|
|
|
|
testConfig.testCommand = 'node ../test/util/mockTestCommand.js'; |
|
|
|
|
|
|
|
testConfig.dir = './mock'; |
|
|
|
|
|
|
|
testConfig.norpc = false; |
|
|
|
|
|
|
|
testConfig.port = 8888; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Installed test will write a fake allFiredEvents to ./ after 4000ms
|
|
|
|
|
|
|
|
// allowing test to pass
|
|
|
|
|
|
|
|
mock.install('Simple.sol', 'command-options.js', testConfig); |
|
|
|
|
|
|
|
shell.exec(script); |
|
|
|
|
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
|
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('contract tests events: tests should pass without errors', () => { |
|
|
|
// Installed test will process.exit(1) and crash truffle if the test isn't
|
|
|
|
if (!process.env.CI) { |
|
|
|
// loaded with the account specified above
|
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
mock.install('Simple.sol', 'testrpc-options.js', testConfig); |
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
shell.exec(script); |
|
|
|
|
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
const testConfig = Object.assign({}, config); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
testConfig.dir = './mock'; |
|
|
|
|
|
|
|
testConfig.norpc = false; |
|
|
|
|
|
|
|
testConfig.port = 8889; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mock.install('Events.sol', 'events.js', testConfig); |
|
|
|
|
|
|
|
shell.exec(script); |
|
|
|
|
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Directory should have coverage report
|
|
|
|
|
|
|
|
assert(pathExists('./coverage') === true, 'script should gen coverage folder'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Coverage should be real.
|
|
|
|
|
|
|
|
// This test is tightly bound to the function names in Simple.sol
|
|
|
|
|
|
|
|
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); |
|
|
|
|
|
|
|
const path = Object.keys(produced)[0]; |
|
|
|
|
|
|
|
assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); |
|
|
|
|
|
|
|
assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); |
|
|
|
|
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
it('trufflejs specifies coverage network: should generate coverage, cleanup and exit(0)', () => { |
|
|
|
|
|
|
|
if (!process.env.CI) { |
|
|
|
|
|
|
|
const trufflejs = |
|
|
|
|
|
|
|
`module.exports = {
|
|
|
|
|
|
|
|
networks: { |
|
|
|
|
|
|
|
development: { |
|
|
|
|
|
|
|
host: "localhost", |
|
|
|
|
|
|
|
port: 8545, |
|
|
|
|
|
|
|
network_id: "*" |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
coverage: { |
|
|
|
|
|
|
|
host: "localhost", |
|
|
|
|
|
|
|
port: 8999, |
|
|
|
|
|
|
|
network_id: "*", |
|
|
|
|
|
|
|
gas: 0xfffffffffff, |
|
|
|
|
|
|
|
gasPrice: 0x01 |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
compilers: { |
|
|
|
|
|
|
|
solc: { |
|
|
|
|
|
|
|
version: "0.5.3", |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
};`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const testConfig = Object.assign({}, config); |
|
|
|
|
|
|
|
testConfig.dir = './mock'; |
|
|
|
|
|
|
|
testConfig.norpc = false; |
|
|
|
|
|
|
|
testConfig.port = 8555; // Manually inspect that port is actually set to 8999
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Directory should be clean
|
|
|
|
|
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Run script (exits 0);
|
|
|
|
|
|
|
|
mock.install('Simple.sol', 'simple.js', testConfig, trufflejs); |
|
|
|
|
|
|
|
shell.exec(script); |
|
|
|
|
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Directory should have coverage report
|
|
|
|
|
|
|
|
assert(pathExists('./coverage') === true, 'script should gen coverage folder'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Coverage should be real.
|
|
|
|
|
|
|
|
// This test is tightly bound to the function names in Simple.sol
|
|
|
|
|
|
|
|
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); |
|
|
|
|
|
|
|
const path = Object.keys(produced)[0]; |
|
|
|
|
|
|
|
assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); |
|
|
|
|
|
|
|
assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); |
|
|
|
|
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it('large contract w/ many unbracketed statements (Oraclize)', () => { |
|
|
|
it('config with test command options string: should run test', () => { |
|
|
|
const trufflejs = |
|
|
|
assert(pathExists('./allFiredEvents') === false, 'should start without: events log'); |
|
|
|
`module.exports = {
|
|
|
|
const testConfig = Object.assign({}, config); |
|
|
|
networks: { |
|
|
|
|
|
|
|
coverage: { |
|
|
|
|
|
|
|
host: "localhost", |
|
|
|
|
|
|
|
network_id: "*", |
|
|
|
|
|
|
|
port: 8555, |
|
|
|
|
|
|
|
gas: 0xfffffffffff, |
|
|
|
|
|
|
|
gasPrice: 0x01 |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
compilers: { |
|
|
|
|
|
|
|
solc: { |
|
|
|
|
|
|
|
version: "0.4.24", |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
};`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Directory should be clean
|
|
|
|
testConfig.testCommand = 'mocha --timeout 5000'; |
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
testConfig.dir = './mock'; |
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
testConfig.norpc = false; |
|
|
|
|
|
|
|
testConfig.port = 8888; |
|
|
|
|
|
|
|
|
|
|
|
// Run script (exits 0);
|
|
|
|
// Installed test will write a fake allFiredEvents to ./ after 4000ms
|
|
|
|
mock.install('Oraclize.sol', 'oraclize.js', config, trufflejs, null, true); |
|
|
|
// allowing test to pass
|
|
|
|
|
|
|
|
mock.install('Simple.sol', 'command-options.js', testConfig); |
|
|
|
shell.exec(script); |
|
|
|
shell.exec(script); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
|
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it('simple contract: should generate coverage, cleanup & exit(0)', () => { |
|
|
|
it('simple contract: should generate coverage, cleanup & exit(0)', () => { |
|
|
|
// Directory should be clean
|
|
|
|
assertCleanInitialState(); |
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Run script (exits 0);
|
|
|
|
// Run script (exits 0);
|
|
|
|
mock.install('Simple.sol', 'simple.js', config); |
|
|
|
mock.install('Simple.sol', 'simple.js', config); |
|
|
|
shell.exec(script); |
|
|
|
shell.exec(script); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
|
|
|
|
|
|
|
|
// Directory should have coverage report
|
|
|
|
assertCoverageGenerated(); |
|
|
|
assert(pathExists('./coverage') === true, 'script should gen coverage folder'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Coverage should be real.
|
|
|
|
// Coverage should be real.
|
|
|
|
// This test is tightly bound to the function names in Simple.sol
|
|
|
|
// This test is tightly bound to the function names in Simple.sol
|
|
|
@ -243,53 +87,46 @@ describe('app', () => { |
|
|
|
const path = Object.keys(produced)[0]; |
|
|
|
const path = Object.keys(produced)[0]; |
|
|
|
assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); |
|
|
|
assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); |
|
|
|
assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); |
|
|
|
assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); |
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it('project uses truffle-config.js: should generate coverage, cleanup and exit(0)', () => { |
|
|
|
it('Oraclize @ solc v.0.4.24 (large, many unbracketed statements)', () => { |
|
|
|
// Directory should be clean
|
|
|
|
const trufflejs = |
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
`module.exports = {
|
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
networks: { |
|
|
|
|
|
|
|
coverage: { |
|
|
|
|
|
|
|
host: "localhost", |
|
|
|
|
|
|
|
network_id: "*", |
|
|
|
|
|
|
|
port: 8555, |
|
|
|
|
|
|
|
gas: 0xfffffffffff, |
|
|
|
|
|
|
|
gasPrice: 0x01 |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
compilers: { |
|
|
|
|
|
|
|
solc: { |
|
|
|
|
|
|
|
version: "0.4.24", |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
};`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertCleanInitialState(); |
|
|
|
|
|
|
|
|
|
|
|
// Run script (exits 0);
|
|
|
|
// Run script (exits 0);
|
|
|
|
mock.install('Simple.sol', 'simple.js', config, null, 'truffle-config.js'); |
|
|
|
mock.install('Oraclize.sol', 'oraclize.js', config, trufflejs, null, true); |
|
|
|
shell.exec(script); |
|
|
|
shell.exec(script); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
|
|
|
|
|
|
|
|
// Directory should have coverage report
|
|
|
|
|
|
|
|
assert(pathExists('./coverage') === true, 'script should gen coverage folder'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Coverage should be real.
|
|
|
|
|
|
|
|
// This test is tightly bound to the function names in Simple.sol
|
|
|
|
|
|
|
|
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); |
|
|
|
|
|
|
|
const path = Object.keys(produced)[0]; |
|
|
|
|
|
|
|
assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); |
|
|
|
|
|
|
|
assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); |
|
|
|
|
|
|
|
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 use pure and view modifiers, including with libraries', () => { |
|
|
|
it('tests use pure and view modifiers, including with libraries', () => { |
|
|
|
// Directory should be clean
|
|
|
|
assertCleanInitialState(); |
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Run script (exits 0);
|
|
|
|
// Run script (exits 0);
|
|
|
|
mock.installLibraryTest(config); |
|
|
|
mock.installLibraryTest(config); |
|
|
|
shell.exec(script); |
|
|
|
shell.exec(script); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
|
|
|
|
|
|
|
|
// Directory should have coverage report
|
|
|
|
assertCoverageGenerated(); |
|
|
|
assert(pathExists('./coverage') === true, 'script should gen coverage folder'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Coverage should be real.
|
|
|
|
// Coverage should be real.
|
|
|
|
// This test is tightly bound to the function names in TotallyPure.sol
|
|
|
|
// This test is tightly bound to the function names in TotallyPure.sol
|
|
|
@ -297,22 +134,18 @@ describe('app', () => { |
|
|
|
const path = Object.keys(produced)[0]; |
|
|
|
const path = Object.keys(produced)[0]; |
|
|
|
assert(produced[path].fnMap['1'].name === 'usesThem', 'coverage.json should map "usesThem"'); |
|
|
|
assert(produced[path].fnMap['1'].name === 'usesThem', 'coverage.json should map "usesThem"'); |
|
|
|
assert(produced[path].fnMap['2'].name === 'isPure', 'coverage.json should map "getX"'); |
|
|
|
assert(produced[path].fnMap['2'].name === 'isPure', 'coverage.json should map "getX"'); |
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it('tests require assets outside of test folder: should generate coverage, cleanup & exit(0)', () => { |
|
|
|
it('tests require assets outside of test folder: should generate coverage, cleanup & exit(0)', () => { |
|
|
|
// Directory should be clean
|
|
|
|
assertCleanInitialState(); |
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Run script (exits 0);
|
|
|
|
// Run script (exits 0);
|
|
|
|
mock.install('Simple.sol', 'requires-externally.js', config); |
|
|
|
mock.install('Simple.sol', 'requires-externally.js', config); |
|
|
|
shell.exec(script); |
|
|
|
shell.exec(script); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
|
|
|
|
|
|
|
|
// Directory should have coverage report
|
|
|
|
assertCoverageGenerated(); |
|
|
|
assert(pathExists('./coverage') === true, 'script should gen coverage folder'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Coverage should be real.
|
|
|
|
// Coverage should be real.
|
|
|
|
// This test is tightly bound to the function names in Simple.sol
|
|
|
|
// This test is tightly bound to the function names in Simple.sol
|
|
|
@ -320,70 +153,59 @@ describe('app', () => { |
|
|
|
const path = Object.keys(produced)[0]; |
|
|
|
const path = Object.keys(produced)[0]; |
|
|
|
assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); |
|
|
|
assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); |
|
|
|
assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); |
|
|
|
assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); |
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it('contract only uses .call: should generate coverage, cleanup & exit(0)', () => { |
|
|
|
it('contract only uses .call: should generate coverage, cleanup & exit(0)', () => { |
|
|
|
// Run against contract that only uses method.call.
|
|
|
|
assertCleanInitialState(); |
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
|
|
|
|
mock.install('OnlyCall.sol', 'only-call.js', config); |
|
|
|
mock.install('OnlyCall.sol', 'only-call.js', config); |
|
|
|
|
|
|
|
|
|
|
|
shell.exec(script); |
|
|
|
shell.exec(script); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
|
|
|
|
|
|
|
|
assert(pathExists('./coverage') === true, 'script should gen coverage folder'); |
|
|
|
assertCoverageGenerated(); |
|
|
|
assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); |
|
|
|
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); |
|
|
|
const path = Object.keys(produced)[0]; |
|
|
|
const path = Object.keys(produced)[0]; |
|
|
|
assert(produced[path].fnMap['1'].name === 'addTwo', 'coverage.json should map "addTwo"'); |
|
|
|
assert(produced[path].fnMap['1'].name === 'addTwo', 'coverage.json should map "addTwo"'); |
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it('contract sends / transfers to instrumented fallback: coverage, cleanup & exit(0)', () => { |
|
|
|
it('contract sends / transfers to instrumented fallback: coverage, cleanup & exit(0)', () => { |
|
|
|
// Skipped due to https://github.com/sc-forks/solidity-coverage/issues/106
|
|
|
|
assertCleanInitialState(); |
|
|
|
// Validate ethereumjs-vm hack to remove gas constraints on transfer() and send()
|
|
|
|
|
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mock.install('Wallet.sol', 'wallet.js', config); |
|
|
|
mock.install('Wallet.sol', 'wallet.js', config); |
|
|
|
shell.exec(script); |
|
|
|
shell.exec(script); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
|
|
|
|
|
|
|
|
assert(pathExists('./coverage') === true, 'script should gen coverage folder'); |
|
|
|
assertCoverageGenerated(); |
|
|
|
assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); |
|
|
|
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); |
|
|
|
const path = Object.keys(produced)[0]; |
|
|
|
const path = Object.keys(produced)[0]; |
|
|
|
assert(produced[path].fnMap['1'].name === 'transferPayment', 'should map "transferPayment"'); |
|
|
|
assert(produced[path].fnMap['1'].name === 'transferPayment', 'should map "transferPayment"'); |
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it('contract uses inheritance: should generate coverage, cleanup & exit(0)', () => { |
|
|
|
it('contract uses inheritance: should generate coverage, cleanup & exit(0)', () => { |
|
|
|
// Run against a contract that 'is' another contract
|
|
|
|
assertCleanInitialState(); |
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
|
|
|
|
mock.installInheritanceTest(config); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mock.installInheritanceTest(config); |
|
|
|
shell.exec(script); |
|
|
|
shell.exec(script); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
|
|
|
|
|
|
|
|
assert(pathExists('./coverage') === true, 'script should gen coverage folder'); |
|
|
|
assertCoverageGenerated(); |
|
|
|
assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); |
|
|
|
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); |
|
|
|
const ownedPath = Object.keys(produced)[0]; |
|
|
|
const ownedPath = Object.keys(produced)[0]; |
|
|
|
const proxyPath = Object.keys(produced)[1]; |
|
|
|
const proxyPath = Object.keys(produced)[1]; |
|
|
|
assert(produced[ownedPath].fnMap['1'].name === 'constructor', 'coverage.json should map "constructor"'); |
|
|
|
assert(produced[ownedPath].fnMap['1'].name === 'constructor', 'coverage.json should map "constructor"'); |
|
|
|
assert(produced[proxyPath].fnMap['1'].name === 'isOwner', 'coverage.json should map "isOwner"'); |
|
|
|
assert(produced[proxyPath].fnMap['1'].name === 'isOwner', 'coverage.json should map "isOwner"'); |
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it('contracts are skipped: should generate coverage, cleanup & exit(0)', () => { |
|
|
|
it('contracts are skipped: should generate coverage, cleanup & exit(0)', () => { |
|
|
|
// Skip instrumentation of some contracts
|
|
|
|
assertCleanInitialState(); |
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
|
|
|
|
const testConfig = Object.assign({}, config); |
|
|
|
const testConfig = Object.assign({}, config); |
|
|
|
|
|
|
|
|
|
|
|
testConfig.skipFiles = ['Owned.sol']; |
|
|
|
testConfig.skipFiles = ['Owned.sol']; |
|
|
@ -392,32 +214,30 @@ describe('app', () => { |
|
|
|
shell.exec(script); |
|
|
|
shell.exec(script); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
|
|
|
|
|
|
|
|
assert(pathExists('./coverage') === true, 'script should gen coverage folder'); |
|
|
|
assertCoverageGenerated(); |
|
|
|
assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); |
|
|
|
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); |
|
|
|
const firstKey = Object.keys(produced)[0]; |
|
|
|
const firstKey = Object.keys(produced)[0]; |
|
|
|
assert(Object.keys(produced).length === 1, 'coverage.json should only contain instrumentation for one contract'); |
|
|
|
assert(Object.keys(produced).length === 1, 'coverage.json should only contain instrumentation for one contract'); |
|
|
|
assert(firstKey.substr(firstKey.length - 9) === 'Proxy.sol', 'coverage.json should only contain instrumentation for Proxy.sol'); |
|
|
|
assert(firstKey.substr(firstKey.length - 9) === 'Proxy.sol', 'coverage.json should only contain instrumentation for Proxy.sol'); |
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it('truffle tests failing: should generate coverage, cleanup & exit(1)', () => { |
|
|
|
it('truffle tests failing: should generate coverage, cleanup & exit(1)', () => { |
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
assertCleanInitialState(); |
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Run with Simple.sol and a failing assertion in a truffle test
|
|
|
|
// Run with Simple.sol and a failing assertion in a truffle test
|
|
|
|
mock.install('Simple.sol', 'truffle-test-fail.js', config); |
|
|
|
mock.install('Simple.sol', 'truffle-test-fail.js', config); |
|
|
|
shell.exec(script); |
|
|
|
shell.exec(script); |
|
|
|
assert(shell.error() !== null, 'script should exit 1'); |
|
|
|
assert(shell.error() !== null, 'script should exit 1'); |
|
|
|
assert(pathExists('./coverage') === true, 'script should gen coverage folder'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === true, 'script should gen coverage.json'); |
|
|
|
assertCoverageGenerated(); |
|
|
|
|
|
|
|
|
|
|
|
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); |
|
|
|
const produced = JSON.parse(fs.readFileSync('./coverage.json', 'utf8')); |
|
|
|
const path = Object.keys(produced)[0]; |
|
|
|
const path = Object.keys(produced)[0]; |
|
|
|
assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); |
|
|
|
assert(produced[path].fnMap['1'].name === 'test', 'coverage.json should map "test"'); |
|
|
|
assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); |
|
|
|
assert(produced[path].fnMap['2'].name === 'getX', 'coverage.json should map "getX"'); |
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it('deployment cost > block gasLimit: should generate coverage, cleanup & exit(0)', () => { |
|
|
|
it('deployment cost > block gasLimit: should generate coverage, cleanup & exit(0)', () => { |
|
|
@ -425,44 +245,27 @@ describe('app', () => { |
|
|
|
mock.install('Expensive.sol', 'block-gas-limit.js', config); |
|
|
|
mock.install('Expensive.sol', 'block-gas-limit.js', config); |
|
|
|
shell.exec(script); |
|
|
|
shell.exec(script); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
assert(shell.error() === null, 'script should not error'); |
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it('truffle crashes: should generate NO coverage, cleanup and exit(1)', () => { |
|
|
|
it('truffle crashes: should generate NO coverage, cleanup and exit(1)', () => { |
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
assertCleanInitialState(); |
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Run with Simple.sol and a syntax error in the truffle test
|
|
|
|
// Run with Simple.sol and a syntax error in the truffle test
|
|
|
|
mock.install('Simple.sol', 'truffle-crash.js', config); |
|
|
|
mock.install('Simple.sol', 'truffle-crash.js', config); |
|
|
|
shell.exec(script); |
|
|
|
shell.exec(script); |
|
|
|
assert(shell.error() !== null, 'script should error'); |
|
|
|
assert(shell.error() !== null, 'script should error'); |
|
|
|
assert(pathExists('./coverage') !== true, 'script should NOT gen coverage folder'); |
|
|
|
assertCoverageNotGenerated(); |
|
|
|
assert(pathExists('./coverage.json') !== true, 'script should NOT gen coverage.json'); |
|
|
|
|
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it('instrumentation errors: should generate NO coverage, cleanup and exit(1)', () => { |
|
|
|
it('instrumentation errors: should generate NO coverage, cleanup and exit(1)', () => { |
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
assertCleanInitialState(); |
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Run with SimpleError.sol (has syntax error) and working truffle test
|
|
|
|
// Run with SimpleError.sol (has syntax error) and working truffle test
|
|
|
|
mock.install('SimpleError.sol', 'simple.js', config); |
|
|
|
mock.install('SimpleError.sol', 'simple.js', config); |
|
|
|
shell.exec(script); |
|
|
|
shell.exec(script); |
|
|
|
assert(shell.error() !== null, 'script should error'); |
|
|
|
assert(shell.error() !== null, 'script should error'); |
|
|
|
assert(pathExists('./coverage') !== true, 'script should NOT gen coverage folder'); |
|
|
|
assertCoverageNotGenerated(); |
|
|
|
assert(pathExists('./coverage.json') !== true, 'script should NOT gen coverage.json'); |
|
|
|
|
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it('no events log produced: should generate NO coverage, cleanup and exit(1)', () => { |
|
|
|
}); |
|
|
|
// Run contract and test that pass but fire no events
|
|
|
|
|
|
|
|
assert(pathExists('./coverage') === false, 'should start without: coverage'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); |
|
|
|
|
|
|
|
mock.install('Empty.sol', 'empty.js', config); |
|
|
|
|
|
|
|
shell.exec(script); |
|
|
|
|
|
|
|
assert(shell.error() !== null, 'script should error'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage') !== true, 'script should NOT gen coverage folder'); |
|
|
|
|
|
|
|
assert(pathExists('./coverage.json') !== true, 'script should NOT gen coverage.json'); |
|
|
|
|
|
|
|
collectGarbage(); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
});*/ |
|
|
|
|
|
|
|