Skip to content

Commit

Permalink
build: fail mocha tests on (forgotten) console logs (#1058)
Browse files Browse the repository at this point in the history
Modify the command "lb-mocha" to load a helper file that detects
calls of console.log/console.error/console.warn APIs and fails
the test suite in such case.

This forces developers to write tests in such way that the console
output remain clean, uncluttered by random logs.
  • Loading branch information
bajtos authored and raymondfeng committed Mar 1, 2018
1 parent 7292883 commit be6e534
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
13 changes: 13 additions & 0 deletions packages/build/bin/run-mocha.js
Expand Up @@ -37,6 +37,19 @@ function run(argv, dryRun) {
);
mochaOpts.unshift('--require', sourceMapRegisterPath);
}

const allowConsoleLogsIx = mochaOpts.indexOf('--allow-console-logs');
if (allowConsoleLogsIx === -1) {
// Fail any tests that are printing to console.
mochaOpts.unshift(
'--require',
require.resolve('../src/fail-on-console-logs')
);
} else {
// Allow tests to print to console, remove --allow-console-logs argument
mochaOpts.splice(allowConsoleLogsIx, 1);
}

const args = [...mochaOpts];

return utils.runCLI('mocha/bin/mocha', args, dryRun);
Expand Down
60 changes: 60 additions & 0 deletions packages/build/src/fail-on-console-logs.js
@@ -0,0 +1,60 @@
// Copyright IBM Corp. 2017,2018. All Rights Reserved.
// Node module: @loopback/build
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

'use strict';

const util = require('util');

const originalConsole = {
log: console.log,
error: console.error,
warn: console.warn,
};

console.log = recordForbiddenCall('log');
console.warn = recordForbiddenCall('warn');
console.error = recordForbiddenCall('error');

const problems = [];

function recordForbiddenCall(methodName) {
return function recordForbiddenConsoleUsage(...args) {
// Print the original message
originalConsole[methodName](...args);

// Find out who called us.
// The first line is the error message,
// the second line points to this very function.
const stack = new Error().stack.split(/\n/).slice(2);

// Mocha reporters are allowed to call console functions
if (/[\/\\]node_modules[\/\\]mocha[\/\\]/.test(stack[0])) {
return;
}

// Record the problem otherwise
const msg = util.format(...args);
problems.push({msg, stack});
}
}

process.on('exit', (code) => {
if (!problems.length) return;
const log = originalConsole.log;

log('\n=== ATTENTION - INVALID USAGE OF CONSOLE LOGS DETECTED ===\n');

for (const p of problems) {
// print the first line of the console log
log(p.msg.split(/\n/)[0]);
// print the stack trace
log(p.stack.join('\n'));
// add an empty line as a delimiter
log('\n');
}

// ensure the process returns non-zero exit code to indicate test failure
process.exitCode = code || 10;
});

0 comments on commit be6e534

Please sign in to comment.