mirror of https://github.com/embarklabs/embark.git
refactor: wire up coverage (#1865)
* refactor: wire up coverage * refactor: coverage now reacts instead of being told what to do
This commit is contained in:
parent
718d19f7d3
commit
7e839e758e
|
@ -18,14 +18,25 @@ export default class Coverage {
|
||||||
constructor(private embark: Embark, options: any) {
|
constructor(private embark: Embark, options: any) {
|
||||||
this.fs = embark.fs;
|
this.fs = embark.fs;
|
||||||
this.fs.ensureDirSync(coverageContractsPath());
|
this.fs.ensureDirSync(coverageContractsPath());
|
||||||
this.originalContractFiles = embark.config.contractsFiles;
|
|
||||||
|
|
||||||
this.contracts = this.getContracts();
|
this.contracts = [];
|
||||||
|
|
||||||
this.embark.events.setCommandHandler("coverage:prepareContracts", async (done) => {
|
if (!options.coverage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.embark.registerActionForEvent('tests:contracts:compile:before', async (contractsFiles, cb) => {
|
||||||
|
const solcVersion = this.embark.config.embarkConfig.versions.solc;
|
||||||
|
const enhancedContracts = contractsFiles.map((file: File) => new ContractEnhanced(file.path, solcVersion));
|
||||||
|
|
||||||
|
this.mergeContracts(enhancedContracts);
|
||||||
await this.prepareContracts();
|
await this.prepareContracts();
|
||||||
this.swapContracts();
|
|
||||||
done();
|
contractsFiles.forEach((cf: any) => {
|
||||||
|
cf.path = path.join(coverageContractsPath(), cf.path);
|
||||||
|
});
|
||||||
|
|
||||||
|
cb(null, contractsFiles);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.embark.events.on("tests:ready", this.pushDeployedContracts.bind(this));
|
this.embark.events.on("tests:ready", this.pushDeployedContracts.bind(this));
|
||||||
|
@ -33,9 +44,14 @@ export default class Coverage {
|
||||||
this.embark.events.on("tests:manualDeploy", this.registerWeb3Contract.bind(this));
|
this.embark.events.on("tests:manualDeploy", this.registerWeb3Contract.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
private getContracts() {
|
private async mergeContracts(contracts: ContractEnhanced[]) {
|
||||||
const solcVersion = this.embark.config.embarkConfig.versions.solc;
|
contracts.forEach((contract: ContractEnhanced) => {
|
||||||
return this.originalContractFiles.map((file) => new ContractEnhanced(file.path, solcVersion));
|
if (this.contracts.some((cc: ContractEnhanced) => cc.filepath === contract.filepath)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.contracts.push(contract);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async prepareContracts() {
|
private async prepareContracts() {
|
||||||
|
@ -46,14 +62,6 @@ export default class Coverage {
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
}
|
}
|
||||||
|
|
||||||
private swapContracts() {
|
|
||||||
this.embark.config.embarkConfig.contracts = this.originalContractFiles.map((file: File) => (
|
|
||||||
path.join(coverageContractsPath(), file.path)
|
|
||||||
));
|
|
||||||
this.embark.config.contractsFiles = [];
|
|
||||||
this.embark.config.reloadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async pushDeployedContracts() {
|
private async pushDeployedContracts() {
|
||||||
const newContracts = await this.getDeployedContracts();
|
const newContracts = await this.getDeployedContracts();
|
||||||
this.deployedContracts = this.deployedContracts.concat(newContracts);
|
this.deployedContracts = this.deployedContracts.concat(newContracts);
|
||||||
|
|
|
@ -9,13 +9,14 @@ const JAVASCRIPT_TEST_MATCH = /^.+\.js$/i;
|
||||||
const TEST_TIMEOUT = 15000; // 15 seconds in milliseconds
|
const TEST_TIMEOUT = 15000; // 15 seconds in milliseconds
|
||||||
|
|
||||||
class MochaTestRunner {
|
class MochaTestRunner {
|
||||||
constructor(embark, _options) {
|
constructor(embark, options) {
|
||||||
this.embark = embark;
|
this.embark = embark;
|
||||||
|
this.events = embark.events;
|
||||||
|
this.plugins = options.plugins;
|
||||||
|
|
||||||
this.files = [];
|
this.files = [];
|
||||||
|
|
||||||
const { events } = embark;
|
this.events.request('tests:runner:register',
|
||||||
events.request('tests:runner:register',
|
|
||||||
'JavaScript (Mocha)',
|
'JavaScript (Mocha)',
|
||||||
this.match.bind(this),
|
this.match.bind(this),
|
||||||
this.addFile.bind(this),
|
this.addFile.bind(this),
|
||||||
|
@ -36,7 +37,7 @@ class MochaTestRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
run(options, cb) {
|
run(options, cb) {
|
||||||
const {events} = this.embark;
|
const {events, plugins} = this;
|
||||||
const {reporter} = options;
|
const {reporter} = options;
|
||||||
|
|
||||||
const Module = require("module");
|
const Module = require("module");
|
||||||
|
@ -76,6 +77,7 @@ class MochaTestRunner {
|
||||||
acctCb(err, accounts);
|
acctCb(err, accounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
events.emit('tests:ready', accounts);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -105,9 +107,15 @@ class MochaTestRunner {
|
||||||
(next) => { // get contract files
|
(next) => { // get contract files
|
||||||
events.request("config:contractsFiles", next);
|
events.request("config:contractsFiles", next);
|
||||||
},
|
},
|
||||||
|
(cf, next) => {
|
||||||
|
plugins.emitAndRunActionsForEvent('tests:contracts:compile:before', cf, next);
|
||||||
|
},
|
||||||
(cf, next) => { // compile contracts
|
(cf, next) => { // compile contracts
|
||||||
events.request("compiler:contracts:compile", cf, next);
|
events.request("compiler:contracts:compile", cf, next);
|
||||||
},
|
},
|
||||||
|
(cc, next) => {
|
||||||
|
plugins.emitAndRunActionsForEvent('tests:contracts:compile:after', cc, next);
|
||||||
|
},
|
||||||
(cc, next) => { // override require
|
(cc, next) => { // override require
|
||||||
compiledContracts = cc;
|
compiledContracts = cc;
|
||||||
|
|
||||||
|
@ -149,12 +157,14 @@ class MochaTestRunner {
|
||||||
}
|
}
|
||||||
|
|
||||||
mocha.run((failures) => {
|
mocha.run((failures) => {
|
||||||
next(null, failures);
|
next();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
], (err, failures) => {
|
], (err) => {
|
||||||
|
events.emit('tests:finished');
|
||||||
|
|
||||||
Module.prototype.require = originalRequire;
|
Module.prototype.require = originalRequire;
|
||||||
cb(err, failures);
|
cb(err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,9 +28,10 @@ const ASSERT_LIB = new File({
|
||||||
});
|
});
|
||||||
|
|
||||||
class SolidityTestRunner {
|
class SolidityTestRunner {
|
||||||
constructor(embark, _options) {
|
constructor(embark, options) {
|
||||||
this.embark = embark;
|
this.embark = embark;
|
||||||
this.events = embark.events;
|
this.events = embark.events;
|
||||||
|
this.plugins = options.plugins;
|
||||||
|
|
||||||
this.files = [];
|
this.files = [];
|
||||||
|
|
||||||
|
@ -56,7 +57,7 @@ class SolidityTestRunner {
|
||||||
|
|
||||||
run(options, cb) {
|
run(options, cb) {
|
||||||
const reporter = new Reporter(options.reporter);
|
const reporter = new Reporter(options.reporter);
|
||||||
const {events} = this;
|
const {events, plugins} = this;
|
||||||
|
|
||||||
if (this.files.length === 0) {
|
if (this.files.length === 0) {
|
||||||
return cb(null, 0);
|
return cb(null, 0);
|
||||||
|
@ -87,9 +88,19 @@ class SolidityTestRunner {
|
||||||
(next) => {
|
(next) => {
|
||||||
events.request("contracts:reset", next);
|
events.request("contracts:reset", next);
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
|
(next) => {
|
||||||
|
plugins.emitAndRunActionsForEvent('tests:contracts:compile:before', contractFiles, next);
|
||||||
|
},
|
||||||
|
*/
|
||||||
(next) => {
|
(next) => {
|
||||||
events.request("compiler:contracts:compile", contractFiles, next);
|
events.request("compiler:contracts:compile", contractFiles, next);
|
||||||
},
|
},
|
||||||
|
/*
|
||||||
|
(cc, next) => {
|
||||||
|
plugins.emitAndRunActionsForEvent('tests:contracts:compile:after', cc, next);
|
||||||
|
},
|
||||||
|
*/
|
||||||
(compiledContracts, next) => {
|
(compiledContracts, next) => {
|
||||||
// TODO: fetch config and use it here
|
// TODO: fetch config and use it here
|
||||||
events.request("contracts:build", { contracts: {} }, compiledContracts, next);
|
events.request("contracts:build", { contracts: {} }, compiledContracts, next);
|
||||||
|
@ -110,6 +121,7 @@ class SolidityTestRunner {
|
||||||
events.request("deployment:contracts:deploy", contractsToDeploy, contractDependencies, next);
|
events.request("deployment:contracts:deploy", contractsToDeploy, contractDependencies, next);
|
||||||
},
|
},
|
||||||
(_result, next) => {
|
(_result, next) => {
|
||||||
|
events.emit('tests:ready');
|
||||||
events.request("blockchain:client:provider", "ethereum", next);
|
events.request("blockchain:client:provider", "ethereum", next);
|
||||||
},
|
},
|
||||||
(bcProvider, next) => {
|
(bcProvider, next) => {
|
||||||
|
|
|
@ -52,6 +52,7 @@
|
||||||
"embark-i18n": "^4.1.1",
|
"embark-i18n": "^4.1.1",
|
||||||
"embark-utils": "^4.1.1",
|
"embark-utils": "^4.1.1",
|
||||||
"fs-extra": "7.0.1",
|
"fs-extra": "7.0.1",
|
||||||
|
"istanbul": "0.4.5",
|
||||||
"mocha": "6.2.0",
|
"mocha": "6.2.0",
|
||||||
"open": "6.4.0"
|
"open": "6.4.0"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { __ } from 'embark-i18n';
|
import { __ } from 'embark-i18n';
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
const chalk = require('chalk');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
const { embarkPath, dappPath, runCmd } = require('embark-utils');
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { COVERAGE_GAS_LIMIT, GAS_LIMIT } from './constants';
|
import { COVERAGE_GAS_LIMIT, GAS_LIMIT } from './constants';
|
||||||
|
|
||||||
|
@ -60,10 +62,32 @@ class TestRunner {
|
||||||
});
|
});
|
||||||
|
|
||||||
async.series(runnerFns, next);
|
async.series(runnerFns, next);
|
||||||
}
|
},
|
||||||
|
(_results, next) => {
|
||||||
|
if (!options.coverage) {
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
const cmd = `${embarkPath('node_modules/.bin/istanbul')} report --root .embark --format html --format lcov`;
|
||||||
|
runCmd(cmd, {silent: false, exitOnError: false}, next);
|
||||||
|
},
|
||||||
], (err) => {
|
], (err) => {
|
||||||
reporter.footer();
|
reporter.footer();
|
||||||
cb(err, reporter.passes, reporter.fails);
|
|
||||||
|
if (!options.coverage) {
|
||||||
|
return cb(err, reporter.passes, reporter.fails);
|
||||||
|
}
|
||||||
|
|
||||||
|
process.stdout.write(chalk`{blue Coverage report created. You can find it here:}\n{white.underline ${dappPath('coverage/index.html')}}\n`);
|
||||||
|
|
||||||
|
if (options.noBrowser) {
|
||||||
|
return cb(err, reporter.passes, reporter.fails);
|
||||||
|
}
|
||||||
|
|
||||||
|
const open = require('open');
|
||||||
|
open(dappPath('coverage/index.html')).then(() => {
|
||||||
|
cb(err, reporter.passes, reporter.fails);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,9 @@ class Reporter {
|
||||||
footer() {
|
footer() {
|
||||||
const total = this.passes + this.fails;
|
const total = this.passes + this.fails;
|
||||||
if (this.fails > 0) {
|
if (this.fails > 0) {
|
||||||
process.stdout.write(`>>> Failed ${this.fails} / ${total} test(s).\n`);
|
process.stdout.write(chalk`{red Failed ${this.fails} / ${total} test(s).}\n`);
|
||||||
} else {
|
} else {
|
||||||
process.stdout.write(`>>> Passed ${this.passes} test(s).\n`);
|
process.stdout.write(chalk`{green Passed ${this.passes} test(s).}\n`);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -882,7 +882,7 @@ class EmbarkController {
|
||||||
engine.registerModuleGroup("compiler");
|
engine.registerModuleGroup("compiler");
|
||||||
engine.registerModuleGroup("contracts");
|
engine.registerModuleGroup("contracts");
|
||||||
engine.registerModuleGroup("pipeline");
|
engine.registerModuleGroup("pipeline");
|
||||||
engine.registerModuleGroup("tests");
|
engine.registerModuleGroup("tests", options);
|
||||||
|
|
||||||
let plugin = engine.plugins.createPlugin('cmdcontrollerplugin', {});
|
let plugin = engine.plugins.createPlugin('cmdcontrollerplugin', {});
|
||||||
plugin.registerActionForEvent("embark:engine:started", async (_params, cb) => {
|
plugin.registerActionForEvent("embark:engine:started", async (_params, cb) => {
|
||||||
|
|
|
@ -189,10 +189,11 @@ class Engine {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
testComponents() {
|
testComponents(options) {
|
||||||
this.registerModulePackage('embark-test-runner');
|
this.registerModulePackage('embark-test-runner');
|
||||||
this.registerModulePackage('embark-solidity-tests');
|
this.registerModulePackage('embark-coverage', {plugins: this.plugins, coverage: options.coverage});
|
||||||
this.registerModulePackage('embark-mocha-tests');
|
this.registerModulePackage('embark-solidity-tests', {plugins: this.plugins, coverage: options.coverage});
|
||||||
|
this.registerModulePackage('embark-mocha-tests', {plugins: this.plugins, coverage: options.coverage});
|
||||||
}
|
}
|
||||||
|
|
||||||
compilerComponents(_options) {
|
compilerComponents(_options) {
|
||||||
|
|
Loading…
Reference in New Issue