embark/lib/tests/run_tests.js
Andre Medeiros a8a9f3e9a8 Setup coverage to listen to the test embark events
This allows us to catch an event to know when the tests are done running. In turn, this will tell us when to save the coverage file and run the report.
2018-09-14 16:31:40 -04:00

166 lines
5.1 KiB
JavaScript

const async = require('async');
const Mocha = require('mocha');
const path = require('path');
const {runCmd} = require('../utils/utils');
const fs = require('../core/fs');
const assert = require('assert');
const Test = require('./test');
const EmbarkSpec = require('./reporter');
function getFilesFromDir(filePath, cb) {
fs.readdir(filePath, (err, files) => {
if (err) {
return cb(err);
}
const testFiles = files.filter((file) => {
// Only keep the .js files
// TODO: make this a configuration in embark.json
return file.substr(-3) === '.js';
}).map((file) => {
return path.join(filePath, file);
});
cb(null, testFiles);
});
}
module.exports = {
run: function (options) {
let failures = 0;
let filePath = options.file;
const loglevel = options.loglevel || 'warn';
if (!filePath) {
filePath = 'test/';
}
async.waterfall([
function checkIfDir(next) {
if (filePath.substr(-1) === '/') {
return next(null, null);
}
fs.stat(filePath, (err, stats) => {
if (err) {
return next(`File "${filePath}" doesn't exist or you don't have permission to it`.red);
}
if (stats.isDirectory()) {
return next(null, null);
}
next(null, [filePath]);
});
},
function getFiles(files, next) {
if (files) {
return next(null, files);
}
getFilesFromDir(filePath, (err, files) => {
if (err) {
console.error('Error while reading the directory');
return next(err);
}
next(null, files);
});
},
function setupGlobalNamespace(files, next) {
// TODO put default config
const test = new Test({loglevel, node: options.node});
global.embark = test;
global.assert = assert;
global.config = test.config.bind(test);
let deprecatedWarning = function () {
console.error(__('%s are not supported anymore', 'EmbarkSpec & deployAll').red);
console.info(__('You can learn about the new revamped tests here: %s', 'https://embark.status.im/docs/testing.html'.underline));
process.exit();
};
global.deployAll = deprecatedWarning;
global.EmbarkSpec = {};
global.EmbarkSpec.deployAll = deprecatedWarning;
// Override require to enable `require('Embark/contracts/contractName');`
const Module = require('module');
const originalRequire = require('module').prototype.require;
Module.prototype.require = function (requireName) {
if (requireName.startsWith('Embark')) {
return test.require(...arguments);
}
return originalRequire.apply(this, arguments);
};
// TODO: this global here might not be necessary at all
global.web3 = global.embark.web3;
global.contract = function (describeName, callback) {
return Mocha.describe(describeName, callback);
};
test.init((err) => {
next(err, files);
});
},
function executeForAllFiles(files, next) {
async.eachLimit(files, 1, (file, eachCb) => {
const mocha = new Mocha();
mocha.reporter(EmbarkSpec, {
events: global.embark.engine.events,
gasDetails: options.gasDetails,
gasLimit: 6000000
});
mocha.addFile(file);
mocha.suite.timeout(0);
mocha.suite.beforeAll('Wait for deploy', (done) => {
if (global.embark.needConfig) {
global.config({});
}
global.embark.onReady((err) => {
done(err);
});
});
mocha.run(function (fails) {
failures += fails;
mocha.suite.removeAllListeners();
// Mocha prints the error already
eachCb();
});
}, next);
},
function runCoverage(next) {
if (!options.coverage) {
return next();
}
global.embark.events.emit('tests:finished', function() {
runCmd(`${fs.embarkPath('node_modules/.bin/istanbul')} report --root .embark --format html`,
{silent: false, exitOnError: false}, (err) => {
if (err) {
return next(err);
}
console.log(`Coverage report created. You can find it here: ${fs.dappPath('coverage/index.html')}\n`);
const opn = require('opn');
const _next = () => { next(); };
opn(fs.dappPath('coverage/index.html'), {wait: false})
.then(() => new Promise(resolve => setTimeout(resolve, 1000)))
.then(_next, _next);
});
});
}
], (err) => {
if (err) {
console.error(err);
process.exit(1);
}
if (failures) {
console.error(` > Total number of failures: ${failures}`.red.bold);
} else {
console.log(' > All tests passed'.green.bold);
}
// Clean contracts folder for next test run
fs.remove('.embark/contracts', (_err) => {
process.exit(failures);
});
});
}
};