2018-10-06 23:42:52 +02:00
|
|
|
// @flow
|
|
|
|
|
import * as React from 'react';
|
2019-02-28 21:53:26 +01:00
|
|
|
import TestRenderer, { type ReactTestRenderer } from 'react-test-renderer'; // eslint-disable-line import/no-extraneous-dependencies
|
|
|
|
|
import act from './act';
|
2019-12-09 05:41:48 -05:00
|
|
|
import { addToCleanupQueue } from './cleanup';
|
2018-10-07 10:59:27 +02:00
|
|
|
import { getByAPI } from './helpers/getByAPI';
|
|
|
|
|
import { queryByAPI } from './helpers/queryByAPI';
|
2020-05-15 09:52:33 +02:00
|
|
|
import { findByAPI } from './helpers/findByAPI';
|
2019-05-28 20:47:06 +02:00
|
|
|
import a11yAPI from './helpers/a11yAPI';
|
2018-11-19 13:51:38 +01:00
|
|
|
import debugShallow from './helpers/debugShallow';
|
|
|
|
|
import debugDeep from './helpers/debugDeep';
|
2018-10-06 23:42:52 +02:00
|
|
|
|
2019-02-28 21:53:26 +01:00
|
|
|
type Options = {
|
2019-05-28 13:31:48 -07:00
|
|
|
wrapper?: React.ComponentType<any>,
|
|
|
|
|
createNodeMock?: (element: React.Element<any>) => any,
|
|
|
|
|
};
|
|
|
|
|
type TestRendererOptions = {
|
2019-02-28 21:53:26 +01:00
|
|
|
createNodeMock: (element: React.Element<any>) => any,
|
|
|
|
|
};
|
|
|
|
|
|
2018-10-06 23:42:52 +02:00
|
|
|
/**
|
|
|
|
|
* Renders test component deeply using react-test-renderer and exposes helpers
|
|
|
|
|
* to assert on the output.
|
|
|
|
|
*/
|
2019-05-28 13:31:48 -07:00
|
|
|
export default function render<T>(
|
|
|
|
|
component: React.Element<T>,
|
|
|
|
|
{ wrapper: Wrapper, createNodeMock }: Options = {}
|
2018-10-06 23:42:52 +02:00
|
|
|
) {
|
2019-05-28 13:31:48 -07:00
|
|
|
const wrap = (innerElement: React.Element<any>) =>
|
|
|
|
|
Wrapper ? <Wrapper>{innerElement}</Wrapper> : innerElement;
|
2019-02-28 21:53:26 +01:00
|
|
|
|
2019-05-28 13:31:48 -07:00
|
|
|
const renderer = renderWithAct(
|
|
|
|
|
wrap(component),
|
|
|
|
|
createNodeMock ? { createNodeMock } : undefined
|
|
|
|
|
);
|
|
|
|
|
const update = updateWithAct(renderer, wrap);
|
2018-10-06 23:42:52 +02:00
|
|
|
const instance = renderer.root;
|
|
|
|
|
|
2019-12-09 05:41:48 -05:00
|
|
|
addToCleanupQueue(renderer.unmount);
|
|
|
|
|
|
2018-10-06 23:42:52 +02:00
|
|
|
return {
|
2018-10-07 10:59:27 +02:00
|
|
|
...getByAPI(instance),
|
|
|
|
|
...queryByAPI(instance),
|
2020-05-15 09:52:33 +02:00
|
|
|
...findByAPI(instance),
|
2019-05-28 20:47:06 +02:00
|
|
|
...a11yAPI(instance),
|
2019-05-28 13:31:48 -07:00
|
|
|
update,
|
|
|
|
|
rerender: update, // alias for `update`
|
2018-10-06 23:42:52 +02:00
|
|
|
unmount: renderer.unmount,
|
2018-10-16 18:00:54 +02:00
|
|
|
toJSON: renderer.toJSON,
|
2018-11-19 13:51:38 +01:00
|
|
|
debug: debug(instance, renderer),
|
2018-10-06 23:42:52 +02:00
|
|
|
};
|
|
|
|
|
}
|
2018-11-19 13:51:38 +01:00
|
|
|
|
2019-02-28 21:53:26 +01:00
|
|
|
function renderWithAct(
|
|
|
|
|
component: React.Element<any>,
|
2019-05-28 13:31:48 -07:00
|
|
|
options?: TestRendererOptions
|
2019-02-28 21:53:26 +01:00
|
|
|
): ReactTestRenderer {
|
|
|
|
|
let renderer: ReactTestRenderer;
|
|
|
|
|
|
|
|
|
|
act(() => {
|
|
|
|
|
renderer = TestRenderer.create(component, options);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return ((renderer: any): ReactTestRenderer);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-28 13:31:48 -07:00
|
|
|
function updateWithAct(
|
|
|
|
|
renderer: ReactTestRenderer,
|
|
|
|
|
wrap: (innerElement: React.Element<any>) => React.Element<any>
|
|
|
|
|
) {
|
2020-05-15 10:10:49 +02:00
|
|
|
return function (component: React.Element<any>) {
|
2019-03-25 10:22:34 -04:00
|
|
|
act(() => {
|
2019-05-28 13:31:48 -07:00
|
|
|
renderer.update(wrap(component));
|
2019-03-25 10:22:34 -04:00
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-19 13:51:38 +01:00
|
|
|
function debug(instance: ReactTestInstance, renderer) {
|
|
|
|
|
function debugImpl(message?: string) {
|
|
|
|
|
return debugDeep(renderer.toJSON(), message);
|
|
|
|
|
}
|
2020-05-15 10:10:49 +02:00
|
|
|
debugImpl.shallow = (message) => debugShallow(instance, message);
|
2018-11-19 13:51:38 +01:00
|
|
|
return debugImpl;
|
|
|
|
|
}
|