react/scripts/jest/matchers/reactTestMatchers.js
Ricky 608edcc90a
[tests] add assertConsole<method>Dev helpers (#28732)
## Overview
**Internal React repo tests only**

Depends on https://github.com/facebook/react/pull/28710

Adds three new assertions:
- `assertConsoleLogDev`
- `assertConsoleWarnDev`
- `assertConsoleErrorDev`

These will replace this pattern:

```js
await expect(async () => {
  await expect(async () => {
    await act(() => {
      root.render(<Fail />)
    });
  }).toThrow();
}).toWarnDev('Warning');
```

With this:

```js
await expect(async () => {
  await act(() => {
    root.render(<Fail />)
  });
}).toThrow();

assertConsoleWarnDev('Warning');
```

It works similar to our other `assertLog` matchers which clear the log
and assert on it, failing the tests if the log is not asserted before
the test ends.

## Diffs

There are a few improvements I also added including better log diffs and
more logging.

When there's a failure, the output will look something like:

<img width="655" alt="Screenshot 2024-04-03 at 11 50 08 AM"
src="https://github.com/facebook/react/assets/2440089/0c4bf1b2-5f63-4204-8af3-09e0c2d752ad">


Check out the test suite for snapshots of all the failures we may log.
2024-04-11 08:19:46 -04:00

49 lines
1.4 KiB
JavaScript

'use strict';
const JestReact = require('jest-react');
const {assertConsoleLogsCleared} = require('internal-test-utils/consoleMock');
// TODO: Move to ReactInternalTestUtils
function captureAssertion(fn) {
// Trick to use a Jest matcher inside another Jest matcher. `fn` contains an
// assertion; if it throws, we capture the error and return it, so the stack
// trace presented to the user points to the original assertion in the
// test file.
try {
fn();
} catch (error) {
return {
pass: false,
message: () => error.message,
};
}
return {pass: true};
}
function assertYieldsWereCleared(Scheduler, caller) {
const actualYields = Scheduler.unstable_clearLog();
if (actualYields.length !== 0) {
const error = Error(
'The event log is not empty. Call assertLog(...) first.'
);
Error.captureStackTrace(error, caller);
throw error;
}
assertConsoleLogsCleared();
}
function toMatchRenderedOutput(ReactNoop, expectedJSX) {
if (typeof ReactNoop.getChildrenAsJSX === 'function') {
const Scheduler = ReactNoop._Scheduler;
assertYieldsWereCleared(Scheduler, toMatchRenderedOutput);
return captureAssertion(() => {
expect(ReactNoop.getChildrenAsJSX()).toEqual(expectedJSX);
});
}
return JestReact.unstable_toMatchRenderedOutput(ReactNoop, expectedJSX);
}
module.exports = {
toMatchRenderedOutput,
};