diff --git a/packages/internal-test-utils/__tests__/ReactInternalTestUtils-test.js b/packages/internal-test-utils/__tests__/ReactInternalTestUtils-test.js
index f7b232171c02a..af2a447f49819 100644
--- a/packages/internal-test-utils/__tests__/ReactInternalTestUtils-test.js
+++ b/packages/internal-test-utils/__tests__/ReactInternalTestUtils-test.js
@@ -309,7 +309,7 @@ describe('ReactInternalTestUtils console mocks', () => {
});
// Helper method to capture assertion failure.
-const expectToWarnAndToThrow = expectBlock => {
+const expectToThrowFailure = expectBlock => {
let caughtError;
try {
expectBlock();
@@ -321,7 +321,7 @@ const expectToWarnAndToThrow = expectBlock => {
};
// Helper method to capture assertion failure with act.
-const awaitExpectToWarnAndToThrow = async expectBlock => {
+const awaitExpectToThrowFailure = async expectBlock => {
let caughtError;
try {
await expectBlock();
@@ -372,7 +372,7 @@ describe('ReactInternalTestUtils console assertions', () => {
await act(() => {
root.render();
});
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await act(() => {
root.render();
});
@@ -392,7 +392,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if first expected log is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.log('Wow');
console.log('Bye');
assertConsoleLogDev(['Hi', 'Wow', 'Bye']);
@@ -413,7 +413,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if middle expected log is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.log('Hi');
console.log('Bye');
assertConsoleLogDev(['Hi', 'Wow', 'Bye']);
@@ -434,7 +434,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if last expected log is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.log('Hi');
console.log('Wow');
assertConsoleLogDev(['Hi', 'Wow', 'Bye']);
@@ -455,7 +455,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if first received log is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.log('Hi');
console.log('Wow');
console.log('Bye');
@@ -477,7 +477,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if middle received log is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.log('Hi');
console.log('Wow');
console.log('Bye');
@@ -499,7 +499,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if last received log is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.log('Hi');
console.log('Wow');
console.log('Bye');
@@ -521,7 +521,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if both expected and received mismatch', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.log('Hi');
console.log('Wow');
console.log('Bye');
@@ -544,7 +544,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if both expected and received mismatch with multiple lines', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.log('Hi\nFoo');
console.log('Wow\nBar');
console.log('Bye\nBaz');
@@ -566,8 +566,22 @@ describe('ReactInternalTestUtils console assertions', () => {
});
// @gate __DEV__
- it('fails if withoutStack passed to assertConsoleLogDev', () => {
- const message = expectToWarnAndToThrow(() => {
+ it('fails if local withoutStack passed to assertConsoleLogDev', () => {
+ const message = expectToThrowFailure(() => {
+ console.log('Hello');
+ assertConsoleLogDev([['Hello', {withoutStack: true}]]);
+ });
+
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleLogDev(expected)
+
+ Do not pass withoutStack to assertConsoleLogDev logs, console.log does not have component stacks."
+ `);
+ });
+
+ // @gate __DEV__
+ it('fails if global withoutStack passed to assertConsoleLogDev', () => {
+ const message = expectToThrowFailure(() => {
console.log('Hello');
assertConsoleLogDev(['Hello'], {withoutStack: true});
});
@@ -583,7 +597,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if the args is greater than %s argument number', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.log('Hi %s', 'Sara', 'extra');
assertConsoleLogDev(['Hi']);
});
@@ -597,7 +611,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if the args is greater than %s argument number for multiple logs', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.log('Hi %s', 'Sara', 'extra');
console.log('Bye %s', 'Sara', 'extra');
assertConsoleLogDev(['Hi', 'Bye']);
@@ -615,7 +629,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if the %s argument number is greater than args', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.log('Hi %s');
assertConsoleLogDev(['Hi']);
});
@@ -629,7 +643,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if the %s argument number is greater than args for multiple logs', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.log('Hi %s');
console.log('Bye %s');
assertConsoleLogDev(['Hi', 'Bye']);
@@ -647,7 +661,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if first arg is not an array', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.log('Hi');
console.log('Bye');
assertConsoleLogDev('Hi', 'Bye');
@@ -680,7 +694,7 @@ describe('ReactInternalTestUtils console assertions', () => {
console.log('Not asserted');
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await waitFor(['foo', 'bar']);
});
expect(message).toMatchInlineSnapshot(`
@@ -722,7 +736,7 @@ describe('ReactInternalTestUtils console assertions', () => {
console.log('Not asserted');
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await waitForThrow('Oh no!');
});
expect(message).toMatchInlineSnapshot(`
@@ -756,7 +770,7 @@ describe('ReactInternalTestUtils console assertions', () => {
root.render();
console.log('Not asserted');
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await waitForPaint(['Urgent: B, Deferred: A']);
});
@@ -791,7 +805,7 @@ describe('ReactInternalTestUtils console assertions', () => {
console.log('Not asserted');
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await waitForAll(['foo', 'bar', 'baz']);
});
expect(message).toMatchInlineSnapshot(`
@@ -826,7 +840,7 @@ describe('ReactInternalTestUtils console assertions', () => {
assertLog([]);
await waitForAll(['foo', 'bar', 'baz']);
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
expect(root).toMatchRenderedOutput(
foobarbaz
);
});
expect(message).toMatchInlineSnapshot(`
@@ -846,7 +860,7 @@ describe('ReactInternalTestUtils console assertions', () => {
describe('assertConsoleWarnDev', () => {
// @gate __DEV__
- it('passes if a warning contains a stack', () => {
+ it('passes if an warning contains a stack', () => {
console.warn('Hello\n in div');
assertConsoleWarnDev(['Hello']);
});
@@ -859,29 +873,49 @@ describe('ReactInternalTestUtils console assertions', () => {
assertConsoleWarnDev(['Hello', 'Good day', 'Bye']);
});
- // @gate __DEV__
- it('passes if warnings without stack explicitly opt out', () => {
- console.warn('Hello');
- assertConsoleWarnDev(['Hello'], {withoutStack: true});
+ it('fails if act is called without assertConsoleWarnDev', async () => {
+ const Yield = ({id}) => {
+ console.warn(id);
+ return id;
+ };
- console.warn('Hello');
- console.warn('Good day');
- console.warn('Bye');
+ function App() {
+ return (
+
+
+
+
+
+ );
+ }
- assertConsoleWarnDev(['Hello', 'Good day', 'Bye'], {withoutStack: true});
- });
+ const root = ReactNoop.createRoot();
+ await act(() => {
+ root.render();
+ });
+ const message = await awaitExpectToThrowFailure(async () => {
+ await act(() => {
+ root.render();
+ });
+ });
- // @gate __DEV__
- it('passes when expected withoutStack number matches the actual one', () => {
- console.warn('Hello\n in div');
- console.warn('Good day');
- console.warn('Bye\n in div');
- assertConsoleWarnDev(['Hello', 'Good day', 'Bye'], {withoutStack: 1});
+ expect(message).toMatchInlineSnapshot(`
+ "asserConsoleLogsCleared(expected)
+
+ console.warn was called without assertConsoleWarnDev:
+ + A
+ + B
+ + C
+
+ You must call one of the assertConsoleDev helpers between each act call."
+ `);
});
- it('fails if act is called without assertConsoleWarnDev', async () => {
+ it('fails if act is called without any assertConsoleDev helpers', async () => {
const Yield = ({id}) => {
+ console.log(id);
console.warn(id);
+ console.error(id);
return id;
};
@@ -899,7 +933,7 @@ describe('ReactInternalTestUtils console assertions', () => {
await act(() => {
root.render();
});
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await act(() => {
root.render();
});
@@ -908,18 +942,28 @@ describe('ReactInternalTestUtils console assertions', () => {
expect(message).toMatchInlineSnapshot(`
"asserConsoleLogsCleared(expected)
+ console.log was called without assertConsoleLogDev:
+ + A
+ + B
+ + C
+
console.warn was called without assertConsoleWarnDev:
+ A
+ B
+ C
+ console.error was called without assertConsoleErrorDev:
+ + A
+ + B
+ + C
+
You must call one of the assertConsoleDev helpers between each act call."
`);
});
// @gate __DEV__
it('fails if first expected warning is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Wow \n in div');
console.warn('Bye \n in div');
assertConsoleWarnDev(['Hi', 'Wow', 'Bye']);
@@ -942,7 +986,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if middle expected warning is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hi \n in div');
console.warn('Bye \n in div');
assertConsoleWarnDev(['Hi', 'Wow', 'Bye']);
@@ -965,7 +1009,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if last expected warning is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hi \n in div');
console.warn('Wow \n in div');
assertConsoleWarnDev(['Hi', 'Wow', 'Bye']);
@@ -988,7 +1032,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if first received warning is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hi \n in div');
console.warn('Wow \n in div');
console.warn('Bye \n in div');
@@ -1012,7 +1056,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if middle received warning is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hi \n in div');
console.warn('Wow \n in div');
console.warn('Bye \n in div');
@@ -1036,7 +1080,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if last received warning is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hi \n in div');
console.warn('Wow \n in div');
console.warn('Bye \n in div');
@@ -1060,7 +1104,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if only warning does not contain a stack', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hello');
assertConsoleWarnDev(['Hello']);
});
@@ -1070,13 +1114,14 @@ describe('ReactInternalTestUtils console assertions', () => {
Missing component stack for:
"Hello"
- If this warning intentionally omits the component stack, add {withoutStack: true} to the assertConsoleWarnDev call."
+ If this warning should omit a component stack, pass [log, {withoutStack: true}].
+ If all warnings should omit the component stack, add {withoutStack: true} to the assertConsoleWarnDev call."
`);
});
// @gate __DEV__
it('fails if first warning does not contain a stack', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hello');
console.warn('Good day\n in div');
console.warn('Bye\n in div');
@@ -1088,12 +1133,14 @@ describe('ReactInternalTestUtils console assertions', () => {
Missing component stack for:
"Hello"
- If this warning intentionally omits the component stack, add {withoutStack: true} to the assertConsoleWarnDev call."
+ If this warning should omit a component stack, pass [log, {withoutStack: true}].
+ If all warnings should omit the component stack, add {withoutStack: true} to the assertConsoleWarnDev call."
`);
});
+
// @gate __DEV__
it('fails if middle warning does not contain a stack', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hello\n in div');
console.warn('Good day');
console.warn('Bye\n in div');
@@ -1105,13 +1152,14 @@ describe('ReactInternalTestUtils console assertions', () => {
Missing component stack for:
"Good day"
- If this warning intentionally omits the component stack, add {withoutStack: true} to the assertConsoleWarnDev call."
+ If this warning should omit a component stack, pass [log, {withoutStack: true}].
+ If all warnings should omit the component stack, add {withoutStack: true} to the assertConsoleWarnDev call."
`);
});
// @gate __DEV__
it('fails if last warning does not contain a stack', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hello\n in div');
console.warn('Good day\n in div');
console.warn('Bye');
@@ -1123,13 +1171,14 @@ describe('ReactInternalTestUtils console assertions', () => {
Missing component stack for:
"Bye"
- If this warning intentionally omits the component stack, add {withoutStack: true} to the assertConsoleWarnDev call."
+ If this warning should omit a component stack, pass [log, {withoutStack: true}].
+ If all warnings should omit the component stack, add {withoutStack: true} to the assertConsoleWarnDev call."
`);
});
// @gate __DEV__
it('fails if all warnings do not contain a stack', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hello');
console.warn('Good day');
console.warn('Bye');
@@ -1147,124 +1196,278 @@ describe('ReactInternalTestUtils console assertions', () => {
Missing component stack for:
"Bye"
- If this warning intentionally omits the component stack, add {withoutStack: true} to the assertConsoleWarnDev call."
+ If this warning should omit a component stack, pass [log, {withoutStack: true}].
+ If all warnings should omit the component stack, add {withoutStack: true} to the assertConsoleWarnDev call."
`);
});
- // @gate __DEV__
- it('fails if only warning is not expected to have a stack, but does', () => {
- const message = expectToWarnAndToThrow(() => {
- console.warn('Hello\n in div');
+ describe('global withoutStack', () => {
+ // @gate __DEV__
+ it('passes if warnings without stack explicitly opt out', () => {
+ console.warn('Hello');
assertConsoleWarnDev(['Hello'], {withoutStack: true});
- });
- expect(message).toMatchInlineSnapshot(`
- "assertConsoleWarnDev(expected)
- Unexpected component stack for:
- "Hello "
-
- If this warning intentionally includes the component stack, remove {withoutStack: true} from the assertConsoleWarnDev() call.
- If you have a mix of warnings with and without stack in one assertConsoleWarnDev() call, pass {withoutStack: N} where N is the number of warnings without stacks."
- `);
- });
-
- // @gate __DEV__
- it('fails if warnings are not expected to have a stack, but some do', () => {
- const message = expectToWarnAndToThrow(() => {
- console.warn('Hello\n in div');
+ console.warn('Hello');
console.warn('Good day');
- console.warn('Bye\n in div');
+ console.warn('Bye');
+
assertConsoleWarnDev(['Hello', 'Good day', 'Bye'], {
withoutStack: true,
});
});
- expect(message).toMatchInlineSnapshot(`
- "assertConsoleWarnDev(expected)
- Unexpected component stack for:
- "Hello "
+ // @gate __DEV__
+ it('fails if withoutStack is invalid null value', () => {
+ const message = expectToThrowFailure(() => {
+ console.warn('Hi');
+ assertConsoleWarnDev(['Hi'], {withoutStack: null});
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleWarnDev(expected)
- Unexpected component stack for:
- "Bye "
+ The second argument must be {withoutStack: true}.
- If this warning intentionally includes the component stack, remove {withoutStack: true} from the assertConsoleWarnDev() call.
- If you have a mix of warnings with and without stack in one assertConsoleWarnDev() call, pass {withoutStack: N} where N is the number of warnings without stacks."
- `);
- });
+ Instead received {"withoutStack":null}."
+ `);
+ assertConsoleWarnDev(['Hi'], {withoutStack: true});
+ });
- // @gate __DEV__
- it('fails if expected withoutStack number does not match the actual one', () => {
- const message = expectToWarnAndToThrow(() => {
+ // @gate __DEV__
+ it('fails if withoutStack is invalid {} value', () => {
+ const message = expectToThrowFailure(() => {
+ console.warn('Hi');
+ assertConsoleWarnDev(['Hi'], {withoutStack: {}});
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleWarnDev(expected)
+
+ The second argument must be {withoutStack: true}.
+
+ Instead received {"withoutStack":{}}."
+ `);
+ assertConsoleWarnDev(['Hi'], {withoutStack: true});
+ });
+
+ // @gate __DEV__
+ it('fails if withoutStack is invalid string value', () => {
+ const message = expectToThrowFailure(() => {
+ console.warn('Hi');
+ assertConsoleWarnDev(['Hi'], {withoutStack: 'haha'});
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleWarnDev(expected)
+
+ The second argument must be {withoutStack: true}.
+
+ Instead received {"withoutStack":"haha"}."
+ `);
+ assertConsoleWarnDev(['Hi'], {withoutStack: true});
+ });
+
+ // @gate __DEV__
+ it('fails if only warning is not expected to have a stack, but does', () => {
+ const message = expectToThrowFailure(() => {
+ console.warn('Hello\n in div');
+ assertConsoleWarnDev(['Hello'], {withoutStack: true});
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleWarnDev(expected)
+
+ Unexpected component stack for:
+ "Hello "
+
+ If this warning should include a component stack, remove {withoutStack: true} from this warning.
+ If all warnings should include the component stack, you may need to remove {withoutStack: true} from the assertConsoleWarnDev call."
+ `);
+ });
+
+ // @gate __DEV__
+ it('fails if warnings are not expected to have a stack, but some do', () => {
+ const message = expectToThrowFailure(() => {
+ console.warn('Hello\n in div');
+ console.warn('Good day');
+ console.warn('Bye\n in div');
+ assertConsoleWarnDev(['Hello', 'Good day', 'Bye'], {
+ withoutStack: true,
+ });
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleWarnDev(expected)
+
+ Unexpected component stack for:
+ "Hello "
+
+ Unexpected component stack for:
+ "Bye "
+
+ If this warning should include a component stack, remove {withoutStack: true} from this warning.
+ If all warnings should include the component stack, you may need to remove {withoutStack: true} from the assertConsoleWarnDev call."
+ `);
+ });
+ });
+ describe('local withoutStack', () => {
+ // @gate __DEV__
+ it('passes when expected withoutStack logs matches the actual logs', () => {
console.warn('Hello\n in div');
console.warn('Good day');
console.warn('Bye\n in div');
- assertConsoleWarnDev(['Hello', 'Good day', 'Bye'], {
- withoutStack: 4,
+ assertConsoleWarnDev([
+ 'Hello',
+ ['Good day', {withoutStack: true}],
+ 'Bye',
+ ]);
+ });
+
+ // @gate __DEV__
+ it('fails if withoutStack is invalid null value', () => {
+ const message = expectToThrowFailure(() => {
+ console.warn('Hi');
+ assertConsoleWarnDev([['Hi', {withoutStack: null}]]);
});
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleWarnDev(expected)
+
+ Log entries that are arrays must be of the form [string, {withoutStack: true}]
+
+ Instead received [string, {"withoutStack":null}]."
+ `);
});
- expect(message).toMatchInlineSnapshot(`
- "assertConsoleWarnDev(expected)
- Expected 4 warnings without a component stack but received 1:
- - Expected warnings
- + Received warnings
+ // @gate __DEV__
+ it('fails if withoutStack is invalid {} value', () => {
+ const message = expectToThrowFailure(() => {
+ console.warn('Hi');
+ assertConsoleWarnDev([['Hi', {withoutStack: {}}]]);
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleWarnDev(expected)
- - Hello
- + Hello
- Good day
- - Bye
- + Bye "
- `);
- });
+ Log entries that are arrays must be of the form [string, {withoutStack: true}]
- // @gate __DEV__
- it('fails if withoutStack is invalid null value', () => {
- const message = expectToWarnAndToThrow(() => {
- console.warn('Hi');
- assertConsoleWarnDev(['Hi'], {withoutStack: null});
+ Instead received [string, {"withoutStack":{}}]."
+ `);
});
- expect(message).toMatchInlineSnapshot(`
- "assertConsoleWarnDev(expected)
- The second argument for assertConsoleWarnDev(), when specified, must be an object. It may have a property called "withoutStack" whose value may be a boolean or number. Instead received object."
- `);
+ // @gate __DEV__
+ it('fails if withoutStack is invalid string value', () => {
+ const message = expectToThrowFailure(() => {
+ console.warn('Hi');
+ assertConsoleWarnDev([['Hi', {withoutStack: 'haha'}]]);
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleWarnDev(expected)
- assertConsoleWarnDev(['Hi'], {withoutStack: true});
- });
+ Log entries that are arrays must be of the form [string, {withoutStack: true}]
- // @gate __DEV__
- it('fails if withoutStack is invalid {} value', () => {
- const message = expectToWarnAndToThrow(() => {
- console.warn('Hi');
- assertConsoleWarnDev(['Hi'], {withoutStack: {}});
+ Instead received [string, {"withoutStack":"haha"}]."
+ `);
});
- expect(message).toMatchInlineSnapshot(`
- "assertConsoleWarnDev(expected)
- The second argument for assertConsoleWarnDev(), when specified, must be an object. It may have a property called "withoutStack" whose value may be a boolean or number. Instead received object."
- `);
+ // @gate __DEV__
+ it('fails if withoutStack is invalid number value', () => {
+ const message = expectToThrowFailure(() => {
+ console.warn('Hi');
+ assertConsoleWarnDev([['Hi', {withoutStack: 4}]]);
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleWarnDev(expected)
- assertConsoleWarnDev(['Hi'], {withoutStack: true});
- });
+ Log entries that are arrays must be of the form [string, {withoutStack: true}]
- // @gate __DEV__
- it('fails if withoutStack is invalid string value', () => {
- const message = expectToWarnAndToThrow(() => {
- console.warn('Hi');
- assertConsoleWarnDev(['Hi'], {withoutStack: 'haha'});
+ Instead received [string, {"withoutStack":4}]."
+ `);
});
- expect(message).toMatchInlineSnapshot(`
- "assertConsoleWarnDev(expected)
- The second argument for assertConsoleWarnDev(), when specified, must be an object. It may have a property called "withoutStack" whose value may be a boolean or number. Instead received string."
- `);
+ // @gate __DEV__
+ it('fails if you forget to wrap local withoutStack in array', () => {
+ const message = expectToThrowFailure(() => {
+ console.warn('Hello\n in div');
+ console.warn('Bye\n in div');
+ assertConsoleWarnDev(['Hello', {withoutStack: true}, 'Bye']);
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleWarnDev(expected)
+
+ Did you forget to wrap a log with withoutStack in an array?
+
+ The expected message for assertConsoleWarnDev() must be a string or an array of length 2.
- assertConsoleWarnDev(['Hi'], {withoutStack: true});
+ Instead received {"withoutStack":true}."
+ `);
+ });
+
+ // @gate __DEV__
+ it('fails if you wrap in an array unnecessarily', () => {
+ const message = expectToThrowFailure(() => {
+ console.warn('Hello');
+ assertConsoleWarnDev([['Hello']]);
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleWarnDev(expected)
+
+ Did you forget to remove the array around the log?
+
+ The expected message for assertConsoleWarnDev() must be a string or an array of length 2, but there's only one item in the array. If this is intentional, remove the extra array."
+ `);
+ });
+
+ // @gate __DEV__
+ it('fails if only warning is not expected to have a stack, but does', () => {
+ const message = expectToThrowFailure(() => {
+ console.warn('Hello\n in div');
+ assertConsoleWarnDev([['Hello', {withoutStack: true}]]);
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleWarnDev(expected)
+
+ Unexpected component stack for:
+ "Hello "
+
+ If this warning should include a component stack, remove {withoutStack: true} from this warning.
+ If all warnings should include the component stack, you may need to remove {withoutStack: true} from the assertConsoleWarnDev call."
+ `);
+ });
+
+ // @gate __DEV__
+ it('fails if warnings are not expected to have a stack, but some do', () => {
+ const message = expectToThrowFailure(() => {
+ console.warn('Hello\n in div');
+ console.warn('Good day');
+ console.warn('Bye\n in div');
+ assertConsoleWarnDev([
+ [
+ 'Hello',
+ {
+ withoutStack: true,
+ },
+ ],
+ 'Good day',
+ [
+ 'Bye',
+ {
+ withoutStack: true,
+ },
+ ],
+ ]);
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleWarnDev(expected)
+
+ Unexpected component stack for:
+ "Hello "
+
+ Unexpected component stack for:
+ "Bye "
+
+ If this warning should include a component stack, remove {withoutStack: true} from this warning.
+ If all warnings should include the component stack, you may need to remove {withoutStack: true} from the assertConsoleWarnDev call."
+ `);
+ });
});
// @gate __DEV__
it('fails if the args is greater than %s argument number', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hi %s', 'Sara', 'extra');
assertConsoleWarnDev(['Hi'], {withoutStack: true});
});
@@ -1278,7 +1481,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if the args is greater than %s argument number for multiple warnings', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hi %s', 'Sara', 'extra');
console.warn('Bye %s', 'Sara', 'extra');
assertConsoleWarnDev(['Hi', 'Bye'], {withoutStack: true});
@@ -1296,7 +1499,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if the %s argument number is greater than args', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hi %s');
assertConsoleWarnDev(['Hi'], {withoutStack: true});
});
@@ -1310,7 +1513,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if the %s argument number is greater than args for multiple warnings', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hi %s');
console.warn('Bye %s');
assertConsoleWarnDev(['Hi', 'Bye'], {withoutStack: true});
@@ -1328,7 +1531,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if component stack is passed twice', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hi %s%s', '\n in div', '\n in div');
assertConsoleWarnDev(['Hi']);
});
@@ -1340,9 +1543,27 @@ describe('ReactInternalTestUtils console assertions', () => {
`);
});
+ // @gate __DEV__
+ it('fails if multiple logs pass component stack twice', () => {
+ const message = expectToThrowFailure(() => {
+ console.warn('Hi %s%s', '\n in div', '\n in div');
+ console.warn('Bye %s%s', '\n in div', '\n in div');
+ assertConsoleWarnDev(['Hi', 'Bye']);
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleWarnDev(expected)
+
+ Received more than one component stack for a warning:
+ "Hi %s%s"
+
+ Received more than one component stack for a warning:
+ "Bye %s%s""
+ `);
+ });
+
// @gate __DEV__
it('fails if multiple strings are passed without an array wrapper for single log', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hi \n in div');
console.warn('Bye \n in div');
assertConsoleWarnDev('Hi', 'Bye');
@@ -1357,7 +1578,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if multiple strings are passed without an array wrapper for multiple logs', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hi \n in div');
console.warn('Bye \n in div');
assertConsoleWarnDev('Hi', 'Bye');
@@ -1372,7 +1593,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails on more than two arguments', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.warn('Hi \n in div');
console.warn('Wow \n in div');
console.warn('Bye \n in div');
@@ -1405,7 +1626,7 @@ describe('ReactInternalTestUtils console assertions', () => {
console.warn('Not asserted');
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await waitFor(['foo', 'bar']);
});
expect(message).toMatchInlineSnapshot(`
@@ -1447,7 +1668,7 @@ describe('ReactInternalTestUtils console assertions', () => {
console.warn('Not asserted');
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await waitForThrow('Oh no!');
});
expect(message).toMatchInlineSnapshot(`
@@ -1481,7 +1702,7 @@ describe('ReactInternalTestUtils console assertions', () => {
root.render();
console.warn('Not asserted');
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await waitForPaint(['Urgent: B, Deferred: A']);
});
@@ -1516,7 +1737,7 @@ describe('ReactInternalTestUtils console assertions', () => {
console.warn('Not asserted');
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await waitForAll(['foo', 'bar', 'baz']);
});
expect(message).toMatchInlineSnapshot(`
@@ -1551,7 +1772,7 @@ describe('ReactInternalTestUtils console assertions', () => {
assertLog([]);
await waitForAll(['foo', 'bar', 'baz']);
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
expect(root).toMatchRenderedOutput(foobarbaz
);
});
expect(message).toMatchInlineSnapshot(`
@@ -1584,26 +1805,6 @@ describe('ReactInternalTestUtils console assertions', () => {
assertConsoleErrorDev(['Hello', 'Good day', 'Bye']);
});
- // @gate __DEV__
- it('passes if errors without stack explicitly opt out', () => {
- console.error('Hello');
- assertConsoleErrorDev(['Hello'], {withoutStack: true});
-
- console.error('Hello');
- console.error('Good day');
- console.error('Bye');
-
- assertConsoleErrorDev(['Hello', 'Good day', 'Bye'], {withoutStack: true});
- });
-
- // @gate __DEV__
- it('passes when expected withoutStack number matches the actual one', () => {
- console.error('Hello\n in div');
- console.error('Good day');
- console.error('Bye\n in div');
- assertConsoleErrorDev(['Hello', 'Good day', 'Bye'], {withoutStack: 1});
- });
-
it('fails if act is called without assertConsoleErrorDev', async () => {
const Yield = ({id}) => {
console.error(id);
@@ -1624,7 +1825,7 @@ describe('ReactInternalTestUtils console assertions', () => {
await act(() => {
root.render();
});
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await act(() => {
root.render();
});
@@ -1664,7 +1865,7 @@ describe('ReactInternalTestUtils console assertions', () => {
await act(() => {
root.render();
});
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await act(() => {
root.render();
});
@@ -1694,7 +1895,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if first expected error is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Wow \n in div');
console.error('Bye \n in div');
assertConsoleErrorDev(['Hi', 'Wow', 'Bye']);
@@ -1717,7 +1918,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if middle expected error is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hi \n in div');
console.error('Bye \n in div');
assertConsoleErrorDev(['Hi', 'Wow', 'Bye']);
@@ -1740,7 +1941,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if last expected error is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hi \n in div');
console.error('Wow \n in div');
assertConsoleErrorDev(['Hi', 'Wow', 'Bye']);
@@ -1763,7 +1964,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if first received error is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hi \n in div');
console.error('Wow \n in div');
console.error('Bye \n in div');
@@ -1787,7 +1988,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if middle received error is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hi \n in div');
console.error('Wow \n in div');
console.error('Bye \n in div');
@@ -1811,7 +2012,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if last received error is not included', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hi \n in div');
console.error('Wow \n in div');
console.error('Bye \n in div');
@@ -1834,7 +2035,7 @@ describe('ReactInternalTestUtils console assertions', () => {
});
// @gate __DEV__
it('fails if only error does not contain a stack', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hello');
assertConsoleErrorDev(['Hello']);
});
@@ -1844,13 +2045,14 @@ describe('ReactInternalTestUtils console assertions', () => {
Missing component stack for:
"Hello"
- If this error intentionally omits the component stack, add {withoutStack: true} to the assertConsoleErrorDev call."
+ If this error should omit a component stack, pass [log, {withoutStack: true}].
+ If all errors should omit the component stack, add {withoutStack: true} to the assertConsoleErrorDev call."
`);
});
// @gate __DEV__
it('fails if first error does not contain a stack', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hello\n in div');
console.error('Good day\n in div');
console.error('Bye');
@@ -1862,12 +2064,13 @@ describe('ReactInternalTestUtils console assertions', () => {
Missing component stack for:
"Bye"
- If this error intentionally omits the component stack, add {withoutStack: true} to the assertConsoleErrorDev call."
+ If this error should omit a component stack, pass [log, {withoutStack: true}].
+ If all errors should omit the component stack, add {withoutStack: true} to the assertConsoleErrorDev call."
`);
});
// @gate __DEV__
it('fails if last error does not contain a stack', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hello');
console.error('Good day\n in div');
console.error('Bye\n in div');
@@ -1879,12 +2082,13 @@ describe('ReactInternalTestUtils console assertions', () => {
Missing component stack for:
"Hello"
- If this error intentionally omits the component stack, add {withoutStack: true} to the assertConsoleErrorDev call."
+ If this error should omit a component stack, pass [log, {withoutStack: true}].
+ If all errors should omit the component stack, add {withoutStack: true} to the assertConsoleErrorDev call."
`);
});
// @gate __DEV__
it('fails if middle error does not contain a stack', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hello\n in div');
console.error('Good day');
console.error('Bye\n in div');
@@ -1896,12 +2100,13 @@ describe('ReactInternalTestUtils console assertions', () => {
Missing component stack for:
"Good day"
- If this error intentionally omits the component stack, add {withoutStack: true} to the assertConsoleErrorDev call."
+ If this error should omit a component stack, pass [log, {withoutStack: true}].
+ If all errors should omit the component stack, add {withoutStack: true} to the assertConsoleErrorDev call."
`);
});
// @gate __DEV__
it('fails if all errors do not contain a stack', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hello');
console.error('Good day');
console.error('Bye');
@@ -1919,148 +2124,278 @@ describe('ReactInternalTestUtils console assertions', () => {
Missing component stack for:
"Bye"
- If this error intentionally omits the component stack, add {withoutStack: true} to the assertConsoleErrorDev call."
+ If this error should omit a component stack, pass [log, {withoutStack: true}].
+ If all errors should omit the component stack, add {withoutStack: true} to the assertConsoleErrorDev call."
`);
});
- // @gate __DEV__
- it('fails if only error is not expected to have a stack, but does', () => {
- const message = expectToWarnAndToThrow(() => {
- console.error('Hello\n in div');
+ describe('global withoutStack', () => {
+ // @gate __DEV__
+ it('passes if errors without stack explicitly opt out', () => {
+ console.error('Hello');
assertConsoleErrorDev(['Hello'], {withoutStack: true});
- });
- expect(message).toMatchInlineSnapshot(`
- "assertConsoleErrorDev(expected)
-
- Unexpected component stack for:
- "Hello "
-
- If this error intentionally includes the component stack, remove {withoutStack: true} from the assertConsoleErrorDev() call.
- If you have a mix of errors with and without stack in one assertConsoleErrorDev() call, pass {withoutStack: N} where N is the number of errors without stacks."
- `);
- });
- // @gate __DEV__
- it('fails if errors are not expected to have a stack, but some do', () => {
- const message = expectToWarnAndToThrow(() => {
- console.error('Hello\n in div');
+ console.error('Hello');
console.error('Good day');
- console.error('Bye\n in div');
+ console.error('Bye');
+
assertConsoleErrorDev(['Hello', 'Good day', 'Bye'], {
withoutStack: true,
});
});
- expect(message).toMatchInlineSnapshot(`
- "assertConsoleErrorDev(expected)
- Unexpected component stack for:
- "Hello "
+ // @gate __DEV__
+ it('fails if withoutStack is invalid null value', () => {
+ const message = expectToThrowFailure(() => {
+ console.error('Hi');
+ assertConsoleErrorDev(['Hi'], {withoutStack: null});
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleErrorDev(expected)
- Unexpected component stack for:
- "Bye "
+ The second argument must be {withoutStack: true}.
- If this error intentionally includes the component stack, remove {withoutStack: true} from the assertConsoleErrorDev() call.
- If you have a mix of errors with and without stack in one assertConsoleErrorDev() call, pass {withoutStack: N} where N is the number of errors without stacks."
- `);
- });
+ Instead received {"withoutStack":null}."
+ `);
+ assertConsoleErrorDev(['Hi'], {withoutStack: true});
+ });
- // @gate __DEV__
- it('fails if expected withoutStack number does not match the actual one', () => {
- const message = expectToWarnAndToThrow(() => {
- console.error('Hello\n in div');
- console.error('Good day');
- console.error('Bye\n in div');
- assertConsoleErrorDev(['Hello', 'Good day', 'Bye'], {
- withoutStack: 4,
+ // @gate __DEV__
+ it('fails if withoutStack is invalid {} value', () => {
+ const message = expectToThrowFailure(() => {
+ console.error('Hi');
+ assertConsoleErrorDev(['Hi'], {withoutStack: {}});
});
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleErrorDev(expected)
+
+ The second argument must be {withoutStack: true}.
+
+ Instead received {"withoutStack":{}}."
+ `);
+ assertConsoleErrorDev(['Hi'], {withoutStack: true});
});
- expect(message).toMatchInlineSnapshot(`
- "assertConsoleErrorDev(expected)
- Expected 4 errors without a component stack but received 1:
- - Expected errors
- + Received errors
+ // @gate __DEV__
+ it('fails if withoutStack is invalid string value', () => {
+ const message = expectToThrowFailure(() => {
+ console.error('Hi');
+ assertConsoleErrorDev(['Hi'], {withoutStack: 'haha'});
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleErrorDev(expected)
- - Hello
- + Hello
- Good day
- - Bye
- + Bye "
- `);
- });
+ The second argument must be {withoutStack: true}.
- // @gate __DEV__
- it('fails if multiple expected withoutStack number does not match the actual one', () => {
- const message = expectToWarnAndToThrow(() => {
+ Instead received {"withoutStack":"haha"}."
+ `);
+ assertConsoleErrorDev(['Hi'], {withoutStack: true});
+ });
+
+ // @gate __DEV__
+ it('fails if only error is not expected to have a stack, but does', () => {
+ const message = expectToThrowFailure(() => {
+ console.error('Hello\n in div');
+ assertConsoleErrorDev(['Hello'], {withoutStack: true});
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleErrorDev(expected)
+
+ Unexpected component stack for:
+ "Hello "
+
+ If this error should include a component stack, remove {withoutStack: true} from this error.
+ If all errors should include the component stack, you may need to remove {withoutStack: true} from the assertConsoleErrorDev call."
+ `);
+ });
+
+ // @gate __DEV__
+ it('fails if errors are not expected to have a stack, but some do', () => {
+ const message = expectToThrowFailure(() => {
+ console.error('Hello\n in div');
+ console.error('Good day');
+ console.error('Bye\n in div');
+ assertConsoleErrorDev(['Hello', 'Good day', 'Bye'], {
+ withoutStack: true,
+ });
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleErrorDev(expected)
+
+ Unexpected component stack for:
+ "Hello "
+
+ Unexpected component stack for:
+ "Bye "
+
+ If this error should include a component stack, remove {withoutStack: true} from this error.
+ If all errors should include the component stack, you may need to remove {withoutStack: true} from the assertConsoleErrorDev call."
+ `);
+ });
+ });
+ describe('local withoutStack', () => {
+ // @gate __DEV__
+ it('passes when expected withoutStack logs matches the actual logs', () => {
console.error('Hello\n in div');
console.error('Good day');
- console.error('Good night');
console.error('Bye\n in div');
- assertConsoleErrorDev(['Hello', 'Good day', 'Good night', 'Bye'], {
- withoutStack: 4,
+ assertConsoleErrorDev([
+ 'Hello',
+ ['Good day', {withoutStack: true}],
+ 'Bye',
+ ]);
+ });
+
+ // @gate __DEV__
+ it('fails if withoutStack is invalid null value', () => {
+ const message = expectToThrowFailure(() => {
+ console.error('Hi');
+ assertConsoleErrorDev([['Hi', {withoutStack: null}]]);
});
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleErrorDev(expected)
+
+ Log entries that are arrays must be of the form [string, {withoutStack: true}]
+
+ Instead received [string, {"withoutStack":null}]."
+ `);
});
- expect(message).toMatchInlineSnapshot(`
- "assertConsoleErrorDev(expected)
- Expected 4 errors without a component stack but received 2:
- - Expected errors
- + Received errors
+ // @gate __DEV__
+ it('fails if withoutStack is invalid {} value', () => {
+ const message = expectToThrowFailure(() => {
+ console.error('Hi');
+ assertConsoleErrorDev([['Hi', {withoutStack: {}}]]);
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleErrorDev(expected)
- - Hello
- + Hello
- Good day
- Good night
- - Bye
- + Bye "
- `);
- });
+ Log entries that are arrays must be of the form [string, {withoutStack: true}]
- // @gate __DEV__
- it('fails if withoutStack is invalid null value', () => {
- const message = expectToWarnAndToThrow(() => {
- console.error('Hi');
- assertConsoleErrorDev(['Hi'], {withoutStack: null});
+ Instead received [string, {"withoutStack":{}}]."
+ `);
});
- expect(message).toMatchInlineSnapshot(`
- "assertConsoleErrorDev(expected)
- The second argument for assertConsoleErrorDev(), when specified, must be an object. It may have a property called "withoutStack" whose value may be a boolean or number. Instead received object."
- `);
- assertConsoleErrorDev(['Hi'], {withoutStack: true});
- });
+ // @gate __DEV__
+ it('fails if withoutStack is invalid string value', () => {
+ const message = expectToThrowFailure(() => {
+ console.error('Hi');
+ assertConsoleErrorDev([['Hi', {withoutStack: 'haha'}]]);
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleErrorDev(expected)
- // @gate __DEV__
- it('fails if withoutStack is invalid {} value', () => {
- const message = expectToWarnAndToThrow(() => {
- console.error('Hi');
- assertConsoleErrorDev(['Hi'], {withoutStack: {}});
+ Log entries that are arrays must be of the form [string, {withoutStack: true}]
+
+ Instead received [string, {"withoutStack":"haha"}]."
+ `);
});
- expect(message).toMatchInlineSnapshot(`
- "assertConsoleErrorDev(expected)
- The second argument for assertConsoleErrorDev(), when specified, must be an object. It may have a property called "withoutStack" whose value may be a boolean or number. Instead received object."
- `);
- assertConsoleErrorDev(['Hi'], {withoutStack: true});
- });
+ // @gate __DEV__
+ it('fails if withoutStack is invalid number value', () => {
+ const message = expectToThrowFailure(() => {
+ console.error('Hi');
+ assertConsoleErrorDev([['Hi', {withoutStack: 4}]]);
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleErrorDev(expected)
- // @gate __DEV__
- it('fails if withoutStack is invalid string value', () => {
- const message = expectToWarnAndToThrow(() => {
- console.error('Hi');
- assertConsoleErrorDev(['Hi'], {withoutStack: 'haha'});
+ Log entries that are arrays must be of the form [string, {withoutStack: true}]
+
+ Instead received [string, {"withoutStack":4}]."
+ `);
});
- expect(message).toMatchInlineSnapshot(`
- "assertConsoleErrorDev(expected)
- The second argument for assertConsoleErrorDev(), when specified, must be an object. It may have a property called "withoutStack" whose value may be a boolean or number. Instead received string."
- `);
- assertConsoleErrorDev(['Hi'], {withoutStack: true});
+ // @gate __DEV__
+ it('fails if you forget to wrap local withoutStack in array', () => {
+ const message = expectToThrowFailure(() => {
+ console.error('Hello\n in div');
+ console.error('Bye\n in div');
+ assertConsoleErrorDev(['Hello', {withoutStack: true}, 'Bye']);
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleErrorDev(expected)
+
+ Did you forget to wrap a log with withoutStack in an array?
+
+ The expected message for assertConsoleErrorDev() must be a string or an array of length 2.
+
+ Instead received {"withoutStack":true}."
+ `);
+ });
+
+ // @gate __DEV__
+ it('fails if you wrap in an array unnecessarily', () => {
+ const message = expectToThrowFailure(() => {
+ console.error('Hello');
+ assertConsoleErrorDev([['Hello']]);
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleErrorDev(expected)
+
+ Did you forget to remove the array around the log?
+
+ The expected message for assertConsoleErrorDev() must be a string or an array of length 2, but there's only one item in the array. If this is intentional, remove the extra array."
+ `);
+ });
+
+ // @gate __DEV__
+ it('fails if only error is not expected to have a stack, but does', () => {
+ const message = expectToThrowFailure(() => {
+ console.error('Hello\n in div');
+ assertConsoleErrorDev([['Hello', {withoutStack: true}]]);
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleErrorDev(expected)
+
+ Unexpected component stack for:
+ "Hello "
+
+ If this error should include a component stack, remove {withoutStack: true} from this error.
+ If all errors should include the component stack, you may need to remove {withoutStack: true} from the assertConsoleErrorDev call."
+ `);
+ });
+
+ // @gate __DEV__
+ it('fails if errors are not expected to have a stack, but some do', () => {
+ const message = expectToThrowFailure(() => {
+ console.error('Hello\n in div');
+ console.error('Good day');
+ console.error('Bye\n in div');
+ assertConsoleErrorDev([
+ [
+ 'Hello',
+ {
+ withoutStack: true,
+ },
+ ],
+ 'Good day',
+ [
+ 'Bye',
+ {
+ withoutStack: true,
+ },
+ ],
+ ]);
+ });
+ expect(message).toMatchInlineSnapshot(`
+ "assertConsoleErrorDev(expected)
+
+ Unexpected component stack for:
+ "Hello "
+
+ Unexpected component stack for:
+ "Bye "
+
+ If this error should include a component stack, remove {withoutStack: true} from this error.
+ If all errors should include the component stack, you may need to remove {withoutStack: true} from the assertConsoleErrorDev call."
+ `);
+ });
});
// @gate __DEV__
it('fails if the args is greater than %s argument number', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hi %s', 'Sara', 'extra');
assertConsoleErrorDev(['Hi'], {withoutStack: true});
});
@@ -2074,7 +2409,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if the args is greater than %s argument number for multiple errors', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hi %s', 'Sara', 'extra');
console.error('Bye %s', 'Sara', 'extra');
assertConsoleErrorDev(['Hi', 'Bye'], {withoutStack: true});
@@ -2092,7 +2427,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if the %s argument number is greater than args', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hi %s');
assertConsoleErrorDev(['Hi'], {withoutStack: true});
});
@@ -2106,7 +2441,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if the %s argument number is greater than args for multiple errors', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hi %s');
console.error('Bye %s');
assertConsoleErrorDev(['Hi', 'Bye'], {withoutStack: true});
@@ -2124,7 +2459,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if component stack is passed twice', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hi %s%s', '\n in div', '\n in div');
assertConsoleErrorDev(['Hi']);
});
@@ -2138,7 +2473,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if multiple logs pass component stack twice', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hi %s%s', '\n in div', '\n in div');
console.error('Bye %s%s', '\n in div', '\n in div');
assertConsoleErrorDev(['Hi', 'Bye']);
@@ -2156,7 +2491,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if multiple strings are passed without an array wrapper for single log', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hi \n in div');
console.error('Bye \n in div');
assertConsoleErrorDev('Hi', 'Bye');
@@ -2171,7 +2506,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails if multiple strings are passed without an array wrapper for multiple logs', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hi \n in div');
console.error('Bye \n in div');
assertConsoleErrorDev('Hi', 'Bye');
@@ -2186,7 +2521,7 @@ describe('ReactInternalTestUtils console assertions', () => {
// @gate __DEV__
it('fails on more than two arguments', () => {
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
console.error('Hi \n in div');
console.error('Wow \n in div');
console.error('Bye \n in div');
@@ -2219,7 +2554,7 @@ describe('ReactInternalTestUtils console assertions', () => {
console.error('Not asserted');
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await waitFor(['foo', 'bar']);
});
expect(message).toMatchInlineSnapshot(`
@@ -2261,7 +2596,7 @@ describe('ReactInternalTestUtils console assertions', () => {
console.error('Not asserted');
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await waitForThrow('Oh no!');
});
expect(message).toMatchInlineSnapshot(`
@@ -2295,7 +2630,7 @@ describe('ReactInternalTestUtils console assertions', () => {
root.render();
console.error('Not asserted');
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await waitForPaint(['Urgent: B, Deferred: A']);
});
@@ -2330,7 +2665,7 @@ describe('ReactInternalTestUtils console assertions', () => {
console.error('Not asserted');
- const message = await awaitExpectToWarnAndToThrow(async () => {
+ const message = await awaitExpectToThrowFailure(async () => {
await waitForAll(['foo', 'bar', 'baz']);
});
expect(message).toMatchInlineSnapshot(`
@@ -2365,7 +2700,7 @@ describe('ReactInternalTestUtils console assertions', () => {
assertLog([]);
await waitForAll(['foo', 'bar', 'baz']);
- const message = expectToWarnAndToThrow(() => {
+ const message = expectToThrowFailure(() => {
expect(root).toMatchRenderedOutput(foobarbaz
);
});
expect(message).toMatchInlineSnapshot(`
diff --git a/packages/internal-test-utils/consoleMock.js b/packages/internal-test-utils/consoleMock.js
index e29a8d6d4ad5f..4601335f40dbe 100644
--- a/packages/internal-test-utils/consoleMock.js
+++ b/packages/internal-test-utils/consoleMock.js
@@ -299,31 +299,28 @@ export function createLogAssertion(
const withoutStack = options.withoutStack;
+ // Warn about invalid global withoutStack values.
if (consoleMethod === 'log' && withoutStack !== undefined) {
- // We don't expect any console.log calls to have a stack.
throwFormattedError(
`Do not pass withoutStack to assertConsoleLogDev, console.log does not have component stacks.`,
);
- } else if (
- withoutStack !== undefined &&
- typeof withoutStack !== 'number' &&
- withoutStack !== true
- ) {
+ } else if (withoutStack !== undefined && withoutStack !== true) {
+ // withoutStack can only have a value true.
throwFormattedError(
- `The second argument for ${matcherName}(), when specified, must be an object. It may have a ` +
- `property called "withoutStack" whose value may be a boolean or number. ` +
- `Instead received ${typeof withoutStack}.`,
+ `The second argument must be {withoutStack: true}.` +
+ `\n\nInstead received ${JSON.stringify(options)}.`,
);
}
const observedLogs = clearObservedErrors();
- const unexpectedLogs = [];
const receivedLogs = [];
- const logsWithoutComponentStack = [];
- const logsWithComponentStack = [];
+ const missingExpectedLogs = Array.from(expectedMessages);
+
+ const unexpectedLogs = [];
+ const unexpectedMissingComponentStack = [];
+ const unexpectedIncludingComponentStack = [];
const logsMismatchingFormat = [];
const logsWithExtraComponentStack = [];
- const missingExpectedLogs = Array.from(expectedMessages);
// Loop over all the observed logs to determine:
// - Which expected logs are missing
@@ -342,7 +339,77 @@ export function createLogAssertion(
return;
}
- const expectedMessage = replaceComponentStack(expectedMessages[index]);
+ let expectedMessage;
+ let expectedWithoutStack;
+ const expectedMessageOrArray = expectedMessages[index];
+ if (
+ expectedMessageOrArray != null &&
+ Array.isArray(expectedMessageOrArray)
+ ) {
+ // Should be in the local form assert([['log', {withoutStack: true}]])
+
+ // Some validations for common mistakes.
+ if (expectedMessageOrArray.length === 1) {
+ throwFormattedError(
+ `Did you forget to remove the array around the log?` +
+ `\n\nThe expected message for ${matcherName}() must be a string or an array of length 2, but there's only one item in the array. If this is intentional, remove the extra array.`,
+ );
+ } else if (expectedMessageOrArray.length !== 2) {
+ throwFormattedError(
+ `The expected message for ${matcherName}() must be a string or an array of length 2. ` +
+ `Instead received ${expectedMessageOrArray}.`,
+ );
+ } else if (consoleMethod === 'log') {
+ // We don't expect any console.log calls to have a stack.
+ throwFormattedError(
+ `Do not pass withoutStack to assertConsoleLogDev logs, console.log does not have component stacks.`,
+ );
+ }
+
+ // Format is correct, check the values.
+ const currentExpectedMessage = expectedMessageOrArray[0];
+ const currentExpectedOptions = expectedMessageOrArray[1];
+ if (
+ typeof currentExpectedMessage !== 'string' ||
+ typeof currentExpectedOptions !== 'object' ||
+ currentExpectedOptions.withoutStack !== true
+ ) {
+ throwFormattedError(
+ `Log entries that are arrays must be of the form [string, {withoutStack: true}]` +
+ `\n\nInstead received [${typeof currentExpectedMessage}, ${JSON.stringify(
+ currentExpectedOptions,
+ )}].`,
+ );
+ }
+
+ expectedMessage = replaceComponentStack(currentExpectedMessage);
+ expectedWithoutStack = expectedMessageOrArray[1].withoutStack;
+ } else if (typeof expectedMessageOrArray === 'string') {
+ // Should be in the form assert(['log']) or assert(['log'], {withoutStack: true})
+ expectedMessage = replaceComponentStack(expectedMessageOrArray[0]);
+ if (consoleMethod === 'log') {
+ expectedWithoutStack = true;
+ } else {
+ expectedWithoutStack = withoutStack;
+ }
+ } else if (
+ typeof expectedMessageOrArray === 'object' &&
+ expectedMessageOrArray != null &&
+ expectedMessageOrArray.withoutStack != null
+ ) {
+ // Special case for common case of a wrong withoutStack value.
+ throwFormattedError(
+ `Did you forget to wrap a log with withoutStack in an array?` +
+ `\n\nThe expected message for ${matcherName}() must be a string or an array of length 2.` +
+ `\n\nInstead received ${JSON.stringify(expectedMessageOrArray)}.`,
+ );
+ } else if (expectedMessageOrArray != null) {
+ throwFormattedError(
+ `The expected message for ${matcherName}() must be a string or an array of length 2. ` +
+ `Instead received ${JSON.stringify(expectedMessageOrArray)}.`,
+ );
+ }
+
const normalizedMessage = replaceComponentStack(message);
receivedLogs.push(normalizedMessage);
@@ -371,15 +438,17 @@ export function createLogAssertion(
});
}
- // Check if log is expected, and if it has a component stack.
+ // Main logic to check if log is expected, with the component stack.
if (
normalizedMessage === expectedMessage ||
normalizedMessage.includes(expectedMessage)
) {
if (isLikelyAComponentStack(normalizedMessage)) {
- logsWithComponentStack.push(normalizedMessage);
- } else {
- logsWithoutComponentStack.push(normalizedMessage);
+ if (expectedWithoutStack === true) {
+ unexpectedIncludingComponentStack.push(normalizedMessage);
+ }
+ } else if (expectedWithoutStack !== true) {
+ unexpectedMissingComponentStack.push(normalizedMessage);
}
// Found expected log, remove it from missing.
@@ -419,53 +488,34 @@ export function createLogAssertion(
);
}
- // Any unexpected component stacks are a failure.
- if (consoleMethod !== 'log') {
- if (typeof withoutStack === 'number') {
- // We're expecting a particular number of warnings without stacks.
- if (withoutStack !== logsWithoutComponentStack.length) {
- throwFormattedError(
- `Expected ${withoutStack} ${logName()}s without a component stack but received ${
- logsWithoutComponentStack.length
- }:\n${printDiff()}`,
- );
- }
- } else if (withoutStack === true) {
- // We're expecting that all warnings won't have the stack.
- // If some warnings have it, it's an error.
- if (logsWithComponentStack.length > 0) {
- throwFormattedError(
- `${logsWithComponentStack
- .map(
- stack =>
- `Unexpected component stack for:\n ${printReceived(
- stack,
- )}`,
- )
- .join(
- '\n\n',
- )}\n\nIf this ${logName()} intentionally includes the component stack, remove ` +
- `{withoutStack: true} from the ${matcherName}() call.\nIf you have a mix of ` +
- `${logName()}s with and without stack in one ${matcherName}() call, pass ` +
- `{withoutStack: N} where N is the number of ${logName()}s without stacks.`,
- );
- }
- } else if (withoutStack === undefined) {
- // We're expecting that all warnings *do* have the stack (default).
- // If some warnings don't have it, it's an error.
- if (logsWithoutComponentStack.length > 0) {
- throwFormattedError(
- `${logsWithoutComponentStack
- .map(
- stack =>
- `Missing component stack for:\n ${printReceived(stack)}`,
- )
- .join(
- '\n\n',
- )}\n\nIf this ${logName()} intentionally omits the component stack, add {withoutStack: true} to the ${matcherName} call.`,
- );
- }
- }
+ // Any logs that include a component stack but shouldn't.
+ if (unexpectedIncludingComponentStack.length > 0) {
+ throwFormattedError(
+ `${unexpectedIncludingComponentStack
+ .map(
+ stack =>
+ `Unexpected component stack for:\n ${printReceived(stack)}`,
+ )
+ .join(
+ '\n\n',
+ )}\n\nIf this ${logName()} should include a component stack, remove {withoutStack: true} from this ${logName()}.` +
+ `\nIf all ${logName()}s should include the component stack, you may need to remove {withoutStack: true} from the ${matcherName} call.`,
+ );
+ }
+
+ // Any logs that are missing a component stack without withoutStack.
+ if (unexpectedMissingComponentStack.length > 0) {
+ throwFormattedError(
+ `${unexpectedMissingComponentStack
+ .map(
+ stack =>
+ `Missing component stack for:\n ${printReceived(stack)}`,
+ )
+ .join(
+ '\n\n',
+ )}\n\nIf this ${logName()} should omit a component stack, pass [log, {withoutStack: true}].` +
+ `\nIf all ${logName()}s should omit the component stack, add {withoutStack: true} to the ${matcherName} call.`,
+ );
}
// Wrong %s formatting is a failure.