Skip to content
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
5 changes: 3 additions & 2 deletions types/react-test-renderer/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
// Type definitions for react-test-renderer 17.0
// Type definitions for react-test-renderer 18.0
// Project: https://facebook.github.io/react/
// Definitions by: Arvitaly <https://github.com/arvitaly>
// Lochbrunner <https://github.com/lochbrunner>
// John Reilly <https://github.com/johnnyreilly>
// John Gozde <https://github.com/jgoz>
// Jessica Franco <https://github.com/Jessidhia>
// Dhruv Jain <https://github.com/maddhruv>
// Sebastian Silbermann <https://github.com/eps1lon>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.8

import { ReactElement, ElementType } from 'react';
export {};

// extracted from:
// - https://github.com/facebook/react/blob/v16.0.0/src/renderers/testing/ReactTestRendererFiberEntry.js
// - https://github.com/facebook/react/blob/v18.0.0/packages/react-test-renderer/index.js
// - https://reactjs.org/docs/test-renderer.html

export interface ReactTestRendererJSON {
Expand Down
94 changes: 94 additions & 0 deletions types/react-test-renderer/v17/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Type definitions for react-test-renderer 17.0
// Project: https://facebook.github.io/react/
// Definitions by: Arvitaly <https://github.com/arvitaly>
// Lochbrunner <https://github.com/lochbrunner>
// John Reilly <https://github.com/johnnyreilly>
// John Gozde <https://github.com/jgoz>
// Jessica Franco <https://github.com/Jessidhia>
// Dhruv Jain <https://github.com/maddhruv>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 2.8

import { ReactElement, ElementType } from 'react';
export {};

// extracted from:
// - https://github.com/facebook/react/blob/v16.0.0/src/renderers/testing/ReactTestRendererFiberEntry.js
// - https://reactjs.org/docs/test-renderer.html

export interface ReactTestRendererJSON {
type: string;
props: { [propName: string]: any };
children: null | ReactTestRendererNode[];
}
export type ReactTestRendererNode = ReactTestRendererJSON | string;
export interface ReactTestRendererTree extends ReactTestRendererJSON {
nodeType: 'component' | 'host';
instance: any;
rendered: null | ReactTestRendererTree | ReactTestRendererTree[];
}
export interface ReactTestInstance {
instance: any;
type: ElementType;
props: { [propName: string]: any };
parent: null | ReactTestInstance;
children: Array<ReactTestInstance | string>;

find(predicate: (node: ReactTestInstance) => boolean): ReactTestInstance;
findByType(type: ElementType): ReactTestInstance;
findByProps(props: { [propName: string]: any }): ReactTestInstance;

findAll(predicate: (node: ReactTestInstance) => boolean, options?: { deep: boolean }): ReactTestInstance[];
findAllByType(type: ElementType, options?: { deep: boolean }): ReactTestInstance[];
findAllByProps(props: { [propName: string]: any }, options?: { deep: boolean }): ReactTestInstance[];
}
export interface ReactTestRenderer {
toJSON(): null | ReactTestRendererJSON | ReactTestRendererJSON[];
toTree(): null | ReactTestRendererTree;
unmount(nextElement?: ReactElement): void;
update(nextElement: ReactElement): void;
getInstance(): null | ReactTestInstance;
root: ReactTestInstance;
}
export interface TestRendererOptions {
createNodeMock(element: ReactElement): any;
}
export function create(nextElement: ReactElement, options?: TestRendererOptions): ReactTestRenderer;

// VoidOrUndefinedOnly is here to forbid any sneaky "Promise" returns.
// the actual return value is always a "DebugPromiseLike".
declare const UNDEFINED_VOID_ONLY: unique symbol;
// tslint:disable-next-line: void-return
type VoidOrUndefinedOnly = void | { [UNDEFINED_VOID_ONLY]: never };
/**
* Wrap any code rendering and triggering updates to your components into `act()` calls.
*
* Ensures that the behavior in your tests matches what happens in the browser
* more closely by executing pending `useEffect`s before returning. This also
* reduces the amount of re-renders done.
*
* @param callback An asynchronous, void callback that will execute as a single, complete React commit.
*
* @see https://reactjs.org/blog/2019/02/06/react-v16.8.0.html#testing-hooks
*/
// VoidOrUndefinedOnly is here to forbid any sneaky return values
export function act(callback: () => Promise<VoidOrUndefinedOnly>): Promise<undefined>;
/**
* Wrap any code rendering and triggering updates to your components into `act()` calls.
*
* Ensures that the behavior in your tests matches what happens in the browser
* more closely by executing pending `useEffect`s before returning. This also
* reduces the amount of re-renders done.
*
* @param callback A synchronous, void callback that will execute as a single, complete React commit.
*
* @see https://reactjs.org/blog/2019/02/06/react-v16.8.0.html#testing-hooks
*/
export function act(callback: () => VoidOrUndefinedOnly): DebugPromiseLike;

// Intentionally doesn't extend PromiseLike<never>.
// Ideally this should be as hard to accidentally use as possible.
export interface DebugPromiseLike {
// the actual then() in here is 1-ary, but that doesn't count as a PromiseLike.
then(onfulfilled: (value: never) => never, onrejected: (reason: never) => never): never;
}
97 changes: 97 additions & 0 deletions types/react-test-renderer/v17/react-test-renderer-tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React = require("react");
import { act, create, ReactTestInstance } from "react-test-renderer";
import { createRenderer } from 'react-test-renderer/shallow';

class TestComponent extends React.Component { }

const renderer = create(React.createElement("div"), {
createNodeMock: (el: React.ReactElement) => {
return {};
}
});

const json = renderer.toJSON();
if (json && !Array.isArray(json)) {
json.type = "t";
json.props = {
prop1: "p",
};
json.children = [json];
}

if (json && Array.isArray(json)) {
json[json.length - 1].type = "t";
json[json.length - 1].props = {
prop1: "p",
};
json[json.length - 1].children = [json[json.length - 1]];
}

const tree = renderer.toTree();
if (tree) {
tree.type = "t";
tree.props = {
prop1: "p",
};
tree.children = [tree];
tree.rendered = tree;
tree.rendered = [tree];
tree.nodeType = "component";
tree.nodeType = "host";
}

renderer.update(React.createElement(TestComponent));

renderer.unmount();
renderer.unmount(React.createElement(TestComponent));

function testInstance(inst: ReactTestInstance) {
inst.children = [inst, "a"];
inst.parent = instance;
inst.parent = null;
inst.props = {
prop1: "p",
};
inst.type = "a";
testInstance(inst.find(n => n.type === "a"));
testInstance(inst.findByProps({ prop1: "p" }));
testInstance(inst.findByType("a"));
testInstance(inst.findByType(TestComponent));
inst.findAll(n => n.type === "div", { deep: true }).map(testInstance);
inst.findAllByProps({ prop1: "p" }, { deep: true }).map(testInstance);
inst.findAllByType("a", { deep: true }).map(testInstance);
inst.findAllByType(TestComponent, { deep: true }).map(testInstance);
}

const instance = renderer.getInstance();
if (instance) {
testInstance(instance);
}

testInstance(renderer.root);

const component = React.createElement(TestComponent);
const shallowRenderer = createRenderer();
shallowRenderer.render(component);
shallowRenderer.getRenderOutput();
shallowRenderer.getMountedInstance();

// Only synchronous, void callbacks are acceptable for act()
act(() => {});
// $ExpectError
act(() => null);
// $ExpectError
Promise.resolve(act(() => {}));

// async act is now acceptable in React 16.9,
// but the result must be void or undefined
Promise.resolve(act(async () => {}));

void (async () => {
act(() => {});

await act(async () => {});
await act(async () => undefined);
// $ExpectError
await act(async () => null);
})();
22 changes: 22 additions & 0 deletions types/react-test-renderer/v17/shallow/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { ReactElement, ReactInstance } from 'react';

export interface ShallowRenderer {
/**
* After `shallowRenderer.render()` has been called, returns mounted instance.
*/
getMountedInstance(): ReactInstance;
/**
* After `shallowRenderer.render()` has been called, returns shallowly rendered output.
*/
getRenderOutput<E extends ReactElement>(): E;
/**
* Similar to `ReactDOM.render` but it doesn't require DOM and only renders a single level deep.
*/
render(element: ReactElement, context?: any): void;
unmount(): void;
}

/**
* Call this in your tests to create a shallow renderer.
*/
export function createRenderer(): ShallowRenderer;
37 changes: 37 additions & 0 deletions types/react-test-renderer/v17/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6",
"dom"
],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"baseUrl": "../../",
"typeRoots": [
"../../"
],"paths": {
"react": [
"react/v17"
],
"react-dom": [
"react-dom/v17"
],
"react-test-renderer": [
"react-test-renderer/v17"
],
"react-test-renderer/*": [
"react-test-renderer/v17/*"
]
},
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"index.d.ts",
"react-test-renderer-tests.ts"
]
}
6 changes: 6 additions & 0 deletions types/react-test-renderer/v17/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "@definitelytyped/dtslint/dt.json",
"rules": {
"no-unnecessary-generics": false
}
}