diff --git a/README.md b/README.md index 5d7e5ab..93af348 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,12 @@ module.exports = { | skipFiles | *Array* | `['Migrations.sol']` | Array of contracts or folders (with paths expressed relative to the `contracts` directory) that should be skipped when doing instrumentation. `Migrations.sol` is skipped by default, and does not need to be added to this configuration option if it is used. | | istanbulReporter | *Array* | ['html', 'lcov', 'text'] | Coverage reporters for Istanbul. Optional reporter replaces the default reporters. | | silent | *Boolean* | false | suppress logging output | +| onServerReady | *Function* | `async (config) => {}` | Function run when server is ready to receive calls, but before the tests execute. Useful if you need to launch the Oraclize/Provable bridge or have preparatory scripts which rely on the server's availability | +| onTestsComplete | *Function* | `async (config) => {}` | Function run immediately after the tests +complete, but before Istanbul reports are generated. | +| onIstanbulComplete | *Function* | `async (config) => {}` | Function run immediately after the Istanbul reports are generated, but before the ganache server is shut down. Useful if you need to clean resources up. | + + ### FAQ diff --git a/dist/truffle.plugin.js b/dist/truffle.plugin.js index 179e80e..07b3883 100644 --- a/dist/truffle.plugin.js +++ b/dist/truffle.plugin.js @@ -58,6 +58,9 @@ async function plugin(config){ config.networks[config.network].port ]); + // Run post-launch server hook; + await api.onServerReady(config); + // Instrument let { targets, @@ -97,8 +100,10 @@ async function plugin(config){ } catch (e) { error = e.stack; } - // Run Istanbul + + await api.onTestsComplete(config); await api.report(); + await api.onIstanbulComplete(config); } catch(e){ error = e; diff --git a/lib/api.js b/lib/api.js index 903279b..7425bbf 100644 --- a/lib/api.js +++ b/lib/api.js @@ -32,6 +32,11 @@ class API { this.cwd = config.cwd || process.cwd(); this.originalContractsDir = config.originalContractsDir + this.defaultHook = () => {}; + this.onServerReady = config.onServerReady || this.defaultHook; + this.onTestsComplete = config.onTestsComplete || this.defaultHook; + this.onIstanbulComplete = config.onIstanbulComplete || this.defaultHook; + this.server = null; this.provider = null; this.defaultPort = 8555; @@ -40,6 +45,7 @@ class API { this.host = config.host || "127.0.0.1"; this.providerOptions = config.providerOptions || {}; + this.skipFiles = config.skipFiles || []; this.log = config.log || console.log; diff --git a/test/integration/projects/test-files/.solcover.js b/test/integration/projects/test-files/.solcover.js index 4278185..7f94ca6 100644 --- a/test/integration/projects/test-files/.solcover.js +++ b/test/integration/projects/test-files/.solcover.js @@ -1,4 +1,10 @@ +// Testing hooks +const fn = (msg, config) => config.logger.log(msg); + module.exports = { silent: process.env.SILENT ? true : false, - istanbulReporter: ['json-summary', 'text'] + istanbulReporter: ['json-summary', 'text'], + onServerReady: fn.bind(null, 'running onServerReady'), + onTestsComplete: fn.bind(null, 'running onTestsComplete'), + onIstanbulComplete: fn.bind(null, 'running onIstanbulComplete') } diff --git a/test/units/truffle/standard.js b/test/units/truffle/standard.js index 17f6726..7b5cbaa 100644 --- a/test/units/truffle/standard.js +++ b/test/units/truffle/standard.js @@ -134,6 +134,23 @@ describe('Truffle Plugin: standard use cases', function() { verify.coverageMissing(missing); }); + it('uses "onServerReady", "onTestsComplete", "onIstanbulComplete"', async function() { + verify.cleanInitialState(); + + truffleConfig.logger = mock.testLogger; + mock.installFullProject('test-files'); + + await plugin(truffleConfig); + + assert( + mock.loggerOutput.val.includes('running onServerReady') && + mock.loggerOutput.val.includes('running onTestsComplete') && + mock.loggerOutput.val.includes('running onIstanbulComplete'), + + `Should run "on" hooks : ${mock.loggerOutput.val}` + ); + }); + it('project with relative path solidity imports', async function() { verify.cleanInitialState(); mock.installFullProject('import-paths');