Skip to content
This repository has been archived by the owner on Oct 11, 2024. It is now read-only.

Commit

Permalink
NODE - add possibility to run all
Browse files Browse the repository at this point in the history
In watch mode it will only rerun affected tests. To rerun all
press a
  • Loading branch information
Christoffer Åström committed Nov 15, 2017
1 parent 1619a33 commit 7d8df0f
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 40 deletions.
13 changes: 1 addition & 12 deletions src/cdp/runner.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
/* eslint no-console: 0, class-methods-use-this: 0 */
const chromeLauncher = require('chrome-launcher');
const unmirror = require('chrome-unmirror');
const readline = require('readline');
const Mediator = require('./mediator');
const connect = require('./connect');

const utils = {
clearLine() {
readline.clearLine(process.stdout, 0);
readline.cursorTo(process.stdout, 0, null);
},
writeLine(msg) {
this.clearLine();
process.stdout.write(`${msg}`);
},
};
const utils = require('../terminal-utils');

class Runner {
constructor(options = { chrome: { chromeFlags: [] }, client: {} }, nyc) {
Expand Down
89 changes: 72 additions & 17 deletions src/node/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/* eslint no-console: 0, max-len: 0, global-require: 0, import/no-dynamic-require: 0, object-curly-newline: 0 */
const readline = require('readline');
const globby = require('globby');
const Mocha = require('mocha');
const chokidar = require('chokidar');
Expand All @@ -7,6 +8,7 @@ const NYC = require('nyc');
const fs = require('fs');
const path = require('path');
const options = require('./options');
const utils = require('../terminal-utils');

class Runner {
constructor(argv, libs) {
Expand All @@ -18,21 +20,42 @@ class Runner {
this.mochaRunner = undefined;
this.mocha = undefined;
this.nyc = undefined;
this.isFirstRun = true;
this.isWrapped = false;
this.isRunning = false;
this.all = true;
this.libs = libs;
}
log(mode, testFiles, srcFiles) {
console.log(`${mode}`);
console.log(' test');
testFiles.forEach((f) => {
console.log(` \u001b[90m${f}\u001b[0m`);
});
console.log(' src');
srcFiles.forEach((f) => {
console.log(` \u001b[90m${f}\u001b[0m`);
});
console.log('\nSave\u001b[90m a test file or source file to run only affected tests\u001b[0m');
console.log('\u001b[90mPress\u001b[0m a \u001b[90mto run all\u001b[0m');
return this;
}
setOnlyFilesFromTestFile(testFile) {
this.onlyTestFiles = [testFile];
const mod = require.cache[testFile];
this.onlySrcFiles = mod.children.filter(m => this.srcFiles.indexOf(m.id) !== -1).map(m => m.id);
const found = mod
.children
.filter(m => this.srcFiles.indexOf(m.id) !== -1)
.map(m => m.id);
this.onlySrcFiles = [...new Set([...found])];
}
setOnlyFilesFromSrcFile(srcFile) {
this.onlyTestFiles = this.testFiles.filter((f) => {
const found = this.testFiles.filter((f) => {
const mod = require.cache[f];
return mod
.children
.filter(m => m.id === srcFile).length !== 0;
});
this.onlyTestFiles = [...new Set([...found])];
this.onlySrcFiles = [srcFile];
}
setOnlyFiles(file) {
Expand Down Expand Up @@ -72,6 +95,7 @@ class Runner {
return this;
}
runTests() {
this.isRunning = true;
this.mochaRunner = this.mocha.run((failures) => {
process.on('exit', () => {
process.exit(failures);
Expand All @@ -81,30 +105,67 @@ class Runner {
if (this.argv.coverage) {
this.nyc.writeCoverageFile();
this.nyc.report();
if (this.argv.watch) {
const mode = this.all ? 'All' : 'Only';
const testFiles = this.all ? [`${this.argv.glob}`] : this.onlyTestFiles;
const srcFiles = this.all ? [`${this.argv.src}`] : this.onlySrcFiles;
this.log(mode, testFiles, srcFiles);
}
}
this.isRunning = false;
});
return this;
}
setupKeyPress() {
if (!this.argv.watch) {
return this;
}
readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);
process.stdin.setEncoding('utf8');
process.stdin.on('keypress', (str) => {
if (str === '\u0003') {
process.exit(0);
}
if (this.isRunning) {
return;
}
switch (str) {
case 'a':
this.all = true;
this.setupAndRunTests(this.testFiles, this.srcFiles);
break;
default: break;
}
});
return this;
}
setup(testFiles, srcFiles) {
if (this.argv.coverage) {
this.nyc.reset();
if (this.isFirstRun) {
if (!this.isWrapped) {
this.nyc.wrap();
this.isWrapped = true;
}
srcFiles.forEach((f) => {
if (require.cache[f]) {
delete require.cache[f];
}
});
utils.writeLine('Source files cache cleared');
}
testFiles.forEach((f) => {
if (require.cache[f]) {
delete require.cache[f];
}
this.mocha.addFile(f);
});
utils.writeLine('Test files cache cleared');
if (this.argv.coverage) {
srcFiles.forEach(f => require(`${f}`));
srcFiles.forEach((f) => {
utils.writeLine(`Loading ${f}`);
require(`${f}`);
});
}
return this;
}
Expand All @@ -114,6 +175,9 @@ class Runner {
this.mochaRunner.removeAllListeners();
}
this.mocha = new this.libs.Mocha(this.argv.mocha);
this.mocha.suite.on('pre-require', (_, file) => {
utils.writeLine(`Loading ${file}`);
});
this.nyc = new this.libs.NYC(this.argv.nyc);
this
.deleteCoverage()
Expand All @@ -124,9 +188,9 @@ class Runner {
this.setupAndRunTests(this.testFiles, this.srcFiles);
if (this.argv.watch) {
this.libs.chokidar.watch(this.argv.watchGlob).on('change', (f) => {
this.isFirstRun = false;
this.all = false;
this.setOnlyFiles(path.resolve(f));
this.setupAndRunTests(this.onlyTestFiles, this.onlySrcFiles);
this.setupAndRunTests(this.onlyTestFiles, this.onlySrcFiles, true);
});
}
}
Expand Down Expand Up @@ -173,6 +237,7 @@ const node = {
handler(argv) {
const runner = new node.Runner(argv, { Mocha, NYC, importCwd, chokidar });
runner
.setupKeyPress()
.setTestFiles()
.setSrcFiles()
.ensureBabelRequire()
Expand All @@ -183,13 +248,3 @@ const node = {
};

module.exports = node;


// if (typeof process.stdin.setRawMode === 'function') {
// process.stdin.setRawMode(true);
// process.stdin.resume();
// process.stdin.setEncoding('hex');
// process.stdin.on('data', (a, b) => {
// console.log(a, b);
// });
// }
6 changes: 0 additions & 6 deletions src/node/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,6 @@ module.exports = {
type: 'array',
alias: 'wg',
},
only: {
description: 'Only run last changed tests',
default: false,
type: 'boolean',
alias: 'o',
},
coverage: {
description: 'Generate coverage',
default: false,
Expand Down
14 changes: 14 additions & 0 deletions src/terminal-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const readline = require('readline');

const utils = {
clearLine() {
readline.clearLine(process.stdout, 0);
readline.cursorTo(process.stdout, 0, null);
},
writeLine(msg) {
this.clearLine();
process.stdout.write(`${msg}`);
},
};

module.exports = utils;
20 changes: 15 additions & 5 deletions test/unit/node/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('Node command', () => {
expect(runner.mochaRunner).to.equal(undefined);
expect(runner.mocha).to.equal(undefined);
expect(runner.nyc).to.equal(undefined);
expect(runner.isFirstRun).to.equal(true);
expect(runner.isWrapped).to.equal(false);
});

it('should set files', () => {
Expand Down Expand Up @@ -126,7 +126,7 @@ describe('Node command', () => {
const wrap = sandbox.stub();
const runner = new Runner({ coverage: true });
runner.nyc = { reset, wrap };
runner.isFirstRun = false;
runner.isWrapped = true;
runner.setup([], []);
expect(reset).to.have.been.calledWithExactly();
expect(wrap.callCount).to.equal(0);
Expand All @@ -149,7 +149,11 @@ describe('Node command', () => {
const procRemoveAllListeners = sandbox.stub(process, 'removeAllListeners');
const removeAllListeners = sandbox.stub();
const mochaRunner = { removeAllListeners };
class Dummy { }
class Dummy {
constructor() {
this.suite = { on: sandbox.stub() };
}
}
const runner = new Runner({}, { Mocha: Dummy, NYC: Dummy });
sandbox.stub(runner, 'deleteCoverage').returnsThis();
sandbox.stub(runner, 'setup').returnsThis();
Expand All @@ -163,7 +167,11 @@ describe('Node command', () => {
it('should setupAndRunTests', () => {
sandbox.stub(process, 'removeAllListeners');
const mochaRunner = { removeAllListeners: sandbox.stub() };
class Dummy { }
class Dummy {
constructor() {
this.suite = { on: sandbox.stub() };
}
}
const runner = new Runner({}, { Mocha: Dummy, NYC: Dummy });
const del = sandbox.stub(runner, 'deleteCoverage').returnsThis();
const set = sandbox.stub(runner, 'setup').returnsThis();
Expand Down Expand Up @@ -196,7 +204,7 @@ describe('Node command', () => {
runner.findFiles = sandbox.stub();
runner.run();
on.callArg(1, 'foo.js');
expect(runner.isFirstRun).to.equal(false);
expect(runner.all).to.equal(false);
expect(runner.setupAndRunTests.callCount).to.equal(2);
});

Expand Down Expand Up @@ -240,12 +248,14 @@ describe('Node command', () => {

it('should call the runner functions', () => {
const origRunner = cmd.Runner;
const setupKeyPress = sandbox.stub().returnsThis();
const setTestFiles = sandbox.stub().returnsThis();
const setSrcFiles = sandbox.stub().returnsThis();
const ensureBabelRequire = sandbox.stub().returnsThis();
const req = sandbox.stub().returnsThis();
const run = sandbox.stub().returnsThis();
class Dummy { }
Dummy.prototype.setupKeyPress = setupKeyPress;
Dummy.prototype.setTestFiles = setTestFiles;
Dummy.prototype.setSrcFiles = setSrcFiles;
Dummy.prototype.ensureBabelRequire = ensureBabelRequire;
Expand Down

0 comments on commit 7d8df0f

Please sign in to comment.