Skip to content

Instantly share code, notes, and snippets.

@rhysburnie
Last active September 19, 2017 01:06
Show Gist options
  • Save rhysburnie/9c44896eab9a100436112089a4385889 to your computer and use it in GitHub Desktop.
Save rhysburnie/9c44896eab9a100436112089a4385889 to your computer and use it in GitHub Desktop.
Suppress certain console.errors
/* eslint-disable no-console */
const originalConsoleError = console.error;
export function restoreConsoleError() {
console.error = originalConsoleError;
}
export function createSuppressedConsoleError(ignoreThese = []) {
if (console.error === originalConsoleError) {
console.error = (...args) => {
let supress = false;
ignoreThese.forEach(ignore => {
if (args[0].indexOf(ignore) === 0) {
supress = true;
}
});
if (supress) return;
originalConsoleError.call(console, ...args);
};
}
}
// creates a sinon.spy instance
// wrapping console.error and
// adds additional method to it
// (spy.errorCallContainsOneOf)
// NOTE: requires you pass it sinon
export function createConsoleErrorSpy(sinon) {
if (!sinon) {
throw new Error('createConsoleErrorSpy requires you pass sinon to it');
}
const spy = sinon.spy(console, 'error');
spy.errorCallContainsOneOf = (messages = [], callIndex) => {
if (messages.length === 0 || typeof callIndex !== 'number') {
return 'errorsContainsOneOf requires an array of messages and an callIndex number';
}
if (!console.error.getCall) {
// the spy must have been `.restore()`d.
return 'the spy has either had no calls or has been restored';
}
const log = console.error.getCall(callIndex).args[0];
let bool = false;
messages.forEach(msg => {
if (log.indexOf(msg) === 0) {
bool = true;
}
});
return bool;
};
return spy;
}
@rhysburnie
Copy link
Author

rhysburnie commented Sep 18, 2017

Created for usage in tests where you only care about if a tests throws and you don't want to see console.errors form the scripts in your terminal.

For example when testing a react component in AVA with a mock if I don't want to see reacts warnings.

UPDATE: Oooops bad example for AVA - only works if one test file - instead use a setup script (see bellow)

test.before(() => {
  createSuppressedConsole([
    'Warning: Failed prop type',
    'Warning: Failed child context type',
    'Warning: Failed context type',
  ]);
});

test.after(restoreConsole);

Should work work fine with non parallel suites
Example something like:

// (untested)
beforeEach(() => {
  createSuppressedConsole([
    'Warning: Failed prop type',
    'Warning: Failed child context type',
    'Warning: Failed context type',
  ]);
});
afterEach(restoreConsole);

You can still detect if an error occured via a sinon spy:

Useful because it wont throw when there is no prop it only warns (but I dont want to see in in the test report)

const spy = sinon.spy(console, 'error');
t.notThrows(() => {
  TestUtils.renderIntoDocument(<SomeComponentThatRequiredAProp />);
});
t.is(spy.callCount, 1); // assuming only one prop required and no other warnings like children, context types  etc

@rhysburnie
Copy link
Author

rhysburnie commented Sep 18, 2017

Create a sinon spy with additional method errorCallContainsOneOf

test(t => {
  const spyError = createConsoleErrorSpy(sinon);
  const expectedErrorLogs = [
     'Error: some error string that begins with' 
  ];
  console.error('Error: some error string that begins with (it looks for index 0 so you can use a common string at the beginning)');
  t.is(spyError.callCount, 1);
  t.true(spyError.errorCallContainsOneOf(expectedErrorLogs, 0));
  spyError.restore(); // remove crap from console.error
});

@rhysburnie
Copy link
Author

Examples in AVA but test suite agnostic (apart from the one that requires sinon)

@rhysburnie
Copy link
Author

rhysburnie commented Sep 19, 2017

IMPORTANT

Turns out when using AVA you can't setup suppression for each test file due to it parallel nature.

So instead in AVA just sett all suppression up in a setup file

Example:

import './setup-browser-env';
import {
  createSuppressedConsoleError,
  restoreConsoleError,
} from './console-utilities';

restoreConsoleError(); // in case previous is kept on --watch (not sure if it does)
createSuppressedConsoleError([
  'Warning: Failed child context type',
  'Warning: Failed context type',
  'Warning: Failed prop type',
]);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment