Protect against passing component stack twice

This is a leftover from #13161 that I forgot to include.
It ensures we don't accidentally write code in the old way and end up passing the stack twice.
This commit is contained in:
Dan Abramov
2018-07-16 22:47:41 +01:00
parent f9358c51c8
commit fd410f43fc
2 changed files with 37 additions and 1 deletions
@@ -161,5 +161,13 @@ describe('toWarnDev', () => {
}).toWarnDev('Hi', {withoutStack: true});
}).toThrow('Received 0 arguments for a message with 1 placeholders');
});
it('fails if stack is passed twice', () => {
expect(() => {
expect(() => {
console.error('Hi %s%s', '\n in div', '\n in div');
}).toWarnDev('Hi');
}).toThrow('Received more than one component stack for a warning');
});
}
});
+29 -1
View File
@@ -24,7 +24,9 @@ const createMatcherFor = consoleMethod =>
const warningsWithoutComponentStack = [];
const warningsWithComponentStack = [];
const unexpectedWarnings = [];
let lastWarningWithMismatchingFormat = null;
let lastWarningWithExtraComponentStack = null;
// Catch errors thrown by the callback,
// But only rethrow them if all test expectations have been satisfied.
@@ -32,6 +34,9 @@ const createMatcherFor = consoleMethod =>
// and result in a test that passes when it shouldn't.
let caughtError;
const isLikelyAComponentStack = message =>
typeof message === 'string' && message.includes('\n in ');
const consoleSpy = (format, ...args) => {
const message = util.format(format, ...args);
const normalizedMessage = normalizeCodeLocInfo(message);
@@ -49,13 +54,25 @@ const createMatcherFor = consoleMethod =>
};
}
// Protect against accidentally passing a component stack
// to warning() which already injects the component stack.
if (
args.length >= 2 &&
isLikelyAComponentStack(args[args.length - 1]) &&
isLikelyAComponentStack(args[args.length - 2])
) {
lastWarningWithExtraComponentStack = {
format,
};
}
for (let index = 0; index < expectedMessages.length; index++) {
const expectedMessage = expectedMessages[index];
if (
normalizedMessage === expectedMessage ||
normalizedMessage.includes(expectedMessage)
) {
if (normalizedMessage.includes('\n in ')) {
if (isLikelyAComponentStack(normalizedMessage)) {
warningsWithComponentStack.push(normalizedMessage);
} else {
warningsWithoutComponentStack.push(normalizedMessage);
@@ -191,6 +208,17 @@ const createMatcherFor = consoleMethod =>
};
}
if (lastWarningWithExtraComponentStack !== null) {
return {
message: () =>
`Received more than one component stack for a warning:\n ${this.utils.printReceived(
lastWarningWithExtraComponentStack.format
)}\nDid you accidentally pass a stack to warning() as the last argument? ` +
`Don't forget warning() already injects the component stack automatically.`,
pass: false,
};
}
return {pass: true};
}
} else {