Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[tests] Disallow unasserted console.log #28708

Merged
merged 3 commits into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions scripts/jest/matchers/__tests__/toWarnDev-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -416,3 +416,20 @@ describe('toWarnDev', () => {
});
}
});

describe('toLogDev', () => {
it('does not fail if warnings do not include a stack', () => {
expect(() => {
if (__DEV__) {
console.log('Hello');
}
}).toLogDev('Hello');
expect(() => {
if (__DEV__) {
console.log('Hello');
console.log('Good day');
console.log('Bye');
}
}).toLogDev(['Hello', 'Good day', 'Bye']);
});
});
5 changes: 4 additions & 1 deletion scripts/jest/matchers/toWarnDev.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,9 @@ const createMatcherFor = (consoleMethod, matcherName) =>
};
}

if (typeof withoutStack === 'number') {
if (consoleMethod === 'log') {
// We don't expect any console.log calls to have a stack.
} else if (typeof withoutStack === 'number') {
// We're expecting a particular number of warnings without stacks.
if (withoutStack !== warningsWithoutComponentStack.length) {
return {
Expand Down Expand Up @@ -309,4 +311,5 @@ const createMatcherFor = (consoleMethod, matcherName) =>
module.exports = {
toWarnDev: createMatcherFor('warn', 'toWarnDev'),
toErrorDev: createMatcherFor('error', 'toErrorDev'),
toLogDev: createMatcherFor('log', 'toLogDev'),
};
25 changes: 23 additions & 2 deletions scripts/jest/setupTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,28 +116,37 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) {
.join('\n')}`
);

const type = methodName === 'log' ? 'log' : 'warning';
const message =
`Expected test not to call ${chalk.bold(
`console.${methodName}()`
)}.\n\n` +
'If the warning is expected, test for it explicitly by:\n' +
`If the ${type} is expected, test for it explicitly by:\n` +
`1. Using the ${chalk.bold('.' + expectedMatcher + '()')} ` +
`matcher, or...\n` +
`2. Mock it out using ${chalk.bold(
'spyOnDev'
)}(console, '${methodName}') or ${chalk.bold(
'spyOnProd'
)}(console, '${methodName}'), and test that the warning occurs.`;
)}(console, '${methodName}'), and test that the ${type} occurs.`;

throw new Error(`${message}\n\n${messages.join('\n\n')}`);
}
};

const unexpectedErrorCallStacks = [];
const unexpectedWarnCallStacks = [];
const unexpectedLogCallStacks = [];

const errorMethod = patchConsoleMethod('error', unexpectedErrorCallStacks);
const warnMethod = patchConsoleMethod('warn', unexpectedWarnCallStacks);
let logMethod;

// Only assert console.log isn't called in CI so you can debug tests in DEV.
// The matchers will still work in DEV, so you can assert locally.
if (process.env.CI) {
logMethod = patchConsoleMethod('log', unexpectedLogCallStacks);
}

const flushAllUnexpectedConsoleCalls = () => {
flushUnexpectedConsoleCalls(
Expand All @@ -152,13 +161,25 @@ if (process.env.REACT_CLASS_EQUIVALENCE_TEST) {
'toWarnDev',
unexpectedWarnCallStacks
);
if (logMethod) {
flushUnexpectedConsoleCalls(
logMethod,
'log',
'toLogDev',
unexpectedLogCallStacks
);
unexpectedLogCallStacks.length = 0;
}
unexpectedErrorCallStacks.length = 0;
unexpectedWarnCallStacks.length = 0;
};

const resetAllUnexpectedConsoleCalls = () => {
unexpectedErrorCallStacks.length = 0;
unexpectedWarnCallStacks.length = 0;
if (logMethod) {
unexpectedLogCallStacks.length = 0;
}
};

beforeEach(resetAllUnexpectedConsoleCalls);
Expand Down