Skip to content

Commit ac77a55

Browse files
committed
inital commit
1 parent 191057e commit ac77a55

File tree

9 files changed

+4690
-0
lines changed

9 files changed

+4690
-0
lines changed

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
flow-typed/

.eslintrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"extends": "@callstack",
3+
"rules": {
4+
"flowtype/no-weak-types": 0
5+
}
6+
}

.flowconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[libs]
2+
flow-typed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
*.log

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# react-native-testing-library
2+
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// flow-typed signature: 9b9f4128694a7f68659d945b81fb78ff
2+
// flow-typed version: 46dfe79a54/react-test-renderer_v16.x.x/flow_>=v0.47.x
3+
4+
// Type definitions for react-test-renderer 16.x.x
5+
// Ported from: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-test-renderer
6+
7+
type ReactComponentInstance = React$Component<any>;
8+
9+
type ReactTestRendererJSON = {
10+
type: string,
11+
props: { [propName: string]: any },
12+
children: null | ReactTestRendererJSON[]
13+
};
14+
15+
type ReactTestRendererTree = ReactTestRendererJSON & {
16+
nodeType: "component" | "host",
17+
instance: ?ReactComponentInstance,
18+
rendered: null | ReactTestRendererTree
19+
};
20+
21+
type ReactTestInstance = {
22+
instance: ?ReactComponentInstance,
23+
type: string | Function,
24+
props: { [propName: string]: any },
25+
parent: null | ReactTestInstance,
26+
children: Array<ReactTestInstance | string>,
27+
28+
find(predicate: (node: ReactTestInstance) => boolean): ReactTestInstance,
29+
findByType(type: React$ElementType): ReactTestInstance,
30+
findByProps(props: { [propName: string]: any }): ReactTestInstance,
31+
32+
findAll(
33+
predicate: (node: ReactTestInstance) => boolean,
34+
options?: { deep: boolean }
35+
): ReactTestInstance[],
36+
findAllByType(
37+
type: React$ElementType,
38+
options?: { deep: boolean }
39+
): ReactTestInstance[],
40+
findAllByProps(
41+
props: { [propName: string]: any },
42+
options?: { deep: boolean }
43+
): ReactTestInstance[]
44+
};
45+
46+
type TestRendererOptions = {
47+
createNodeMock(element: React$Element<any>): any
48+
};
49+
50+
declare module "react-test-renderer" {
51+
declare export type ReactTestRenderer = {
52+
toJSON(): null | ReactTestRendererJSON,
53+
toTree(): null | ReactTestRendererTree,
54+
unmount(nextElement?: React$Element<any>): void,
55+
update(nextElement: React$Element<any>): void,
56+
getInstance(): ?ReactComponentInstance,
57+
root: ReactTestInstance
58+
};
59+
60+
declare function create(
61+
nextElement: React$Element<any>,
62+
options?: TestRendererOptions
63+
): ReactTestRenderer;
64+
}
65+
66+
declare module "react-test-renderer/shallow" {
67+
declare export default class ShallowRenderer {
68+
static createRenderer(): ShallowRenderer;
69+
getMountedInstance(): ReactTestInstance;
70+
getRenderOutput<E: React$Element<any>>(): E;
71+
getRenderOutput(): React$Element<any>;
72+
render(element: React$Element<any>, context?: any): void;
73+
unmount(): void;
74+
}
75+
}

package.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "react-native-testing-library",
3+
"version": "0.0.0",
4+
"description": "Simple React Native testing utilities helping you write better tests with less effort",
5+
"main": "src/index.js",
6+
"repository": "[email protected]:callstack/react-native-testing-library.git",
7+
"author": "Michał Pierzchała <[email protected]>",
8+
"license": "MIT",
9+
"private": false,
10+
"devDependencies": {
11+
"@callstack/eslint-config": "^2.0.0",
12+
"babel-jest": "^23.6.0",
13+
"eslint": "^5.6.1",
14+
"flow-bin": "^0.81.0",
15+
"jest": "^23.6.0",
16+
"pretty-format": "^23.6.0",
17+
"react": "^16.5.2",
18+
"react-test-renderer": "^16.5.2"
19+
},
20+
"peerDependencies": {
21+
"pretty-format": ">=20.0.0",
22+
"react": ">=16.0.0",
23+
"react-test-renderer": ">= 16.0.0"
24+
},
25+
"dependencies": {
26+
"react-is": "^16.5.2"
27+
}
28+
}

src/index.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// @flow
2+
import * as React from 'react';
3+
import { isValidElementType } from 'react-is';
4+
import TestRenderer from 'react-test-renderer'; // eslint-disable-line import/no-extraneous-dependencies
5+
import ShallowRenderer from 'react-test-renderer/shallow'; // eslint-disable-line import/no-extraneous-dependencies
6+
import prettyFormat, { plugins } from 'pretty-format'; // eslint-disable-line import/no-extraneous-dependencies
7+
8+
const getNodeByName = (node, name) =>
9+
node.type.name === name ||
10+
node.type.displayName === name ||
11+
node.type === name;
12+
13+
const getNodeByText = (node, text) =>
14+
(getNodeByName(node, 'Text') || getNodeByName(node, 'TextInput')) &&
15+
(typeof text === 'string'
16+
? text === node.props.children
17+
: text.test(node.props.children));
18+
19+
/**
20+
* Wait for microtask queue to flush
21+
*/
22+
export const flushMicrotasksQueue = (): Promise<any> =>
23+
new Promise(resolve => setImmediate(resolve));
24+
25+
/**
26+
* Renders test component deeply using react-test-renderer and exposes helpers
27+
* to assert on the output.
28+
*/
29+
export const render = (component: React.Element<*>) => {
30+
const renderer = TestRenderer.create(component);
31+
const instance = renderer.root;
32+
33+
return {
34+
instance,
35+
renderer,
36+
getByTestId: (testID: string) => instance.findByProps({ testID }),
37+
getByName: (name: string) =>
38+
instance.find(node => getNodeByName(node, name)),
39+
getAllByName: (name: string) =>
40+
instance.findAll(node => getNodeByName(node, name)),
41+
getByText: (text: string | RegExp) =>
42+
instance.find(node => getNodeByText(node, text)),
43+
getAllByText: (text: string | RegExp) =>
44+
instance.findAll(node => getNodeByText(node, text)),
45+
getByProps: (props: { [propName: string]: any }) =>
46+
instance.findByProps(props),
47+
getAllByProps: (props: { [propName: string]: any }) =>
48+
instance.findAllByProps(props),
49+
};
50+
};
51+
52+
/**
53+
* Renders test component shallowly using react-test-renderer/shallow
54+
*/
55+
export const shallow = (instance: ReactTestInstance | React.Element<*>) => {
56+
const renderer = new ShallowRenderer();
57+
if (isValidElementType(instance)) {
58+
// $FlowFixMe - instance is React.Element<*> in this branch
59+
renderer.render(instance);
60+
} else {
61+
renderer.render(React.createElement(instance.type, instance.props));
62+
}
63+
const result = renderer.getRenderOutput();
64+
65+
return result;
66+
};
67+
68+
/**
69+
* Log pretty-printed shallow test component instance
70+
*/
71+
export const debug = (
72+
instance: ReactTestInstance | React.Element<*>,
73+
message?: any
74+
) => {
75+
// eslint-disable-next-line no-console
76+
console.log(
77+
prettyFormat(shallow(instance), {
78+
plugins: [plugins.ReactTestComponent, plugins.ReactElement],
79+
}),
80+
message
81+
);
82+
};

0 commit comments

Comments
 (0)