Skip to content

Commit 404b4dd

Browse files
committed
Merge remote-tracking branch 'origin' into feat/fire-event-api
2 parents 16d0a2b + 9d14406 commit 404b4dd

File tree

8 files changed

+190
-134
lines changed

8 files changed

+190
-134
lines changed

src/__tests__/render.test.js

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,7 @@ test('getByTestId', () => {
7272
const component = getByTestId('bananaFresh');
7373

7474
expect(component.props.children).toBe('not fresh');
75-
expect(() => {
76-
getByTestId('InExistent');
77-
}).toThrow();
75+
expect(() => getByTestId('InExistent')).toThrow();
7876
});
7977

8078
test('getByName', () => {
@@ -91,9 +89,7 @@ test('getByName', () => {
9189

9290
expect(bananaFresh.props.children).toBe('not fresh');
9391

94-
expect(() => {
95-
getByName('InExistent');
96-
}).toThrow();
92+
expect(() => getByName('InExistent')).toThrow();
9793
});
9894

9995
test('getAllByName', () => {
@@ -103,7 +99,7 @@ test('getAllByName', () => {
10399
expect(text.props.children).toBe('Is the banana fresh?');
104100
expect(status.props.children).toBe('not fresh');
105101
expect(button.props.children).toBe('Change freshness!');
106-
expect(getAllByName('InExistent')).toHaveLength(0);
102+
expect(() => getAllByName('InExistent')).toThrow();
107103
});
108104

109105
test('getByText', () => {
@@ -115,35 +111,31 @@ test('getByText', () => {
115111
const sameButton = getByText('not fresh');
116112

117113
expect(sameButton.props.children).toBe('not fresh');
118-
expect(() => {
119-
getByText('InExistent');
120-
}).toThrow();
114+
expect(() => getByText('InExistent')).toThrow();
121115
});
122116

123117
test('getAllByText', () => {
124118
const { getAllByText } = render(<Banana />);
125119
const button = getAllByText(/fresh/i);
126120

127121
expect(button).toHaveLength(3);
128-
expect(getAllByText('InExistent')).toHaveLength(0);
122+
expect(() => getAllByText('InExistent')).toThrow();
129123
});
130124

131125
test('getByProps', () => {
132126
const { getByProps } = render(<Banana />);
133127
const primaryType = getByProps({ type: 'primary' });
134128

135129
expect(primaryType.props.children).toBe('Change freshness!');
136-
expect(() => {
137-
getByProps({ type: 'inexistent' });
138-
}).toThrow();
130+
expect(() => getByProps({ type: 'inexistent' })).toThrow();
139131
});
140132

141133
test('getAllByProps', () => {
142134
const { getAllByProps } = render(<Banana />);
143135
const primaryTypes = getAllByProps({ type: 'primary' });
144136

145137
expect(primaryTypes).toHaveLength(1);
146-
expect(getAllByProps({ type: 'inexistent' })).toHaveLength(0);
138+
expect(() => getAllByProps({ type: 'inexistent' })).toThrow();
147139
});
148140

149141
test('update', () => {

src/debug.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// @flow
2+
import * as React from 'react';
3+
import prettyFormat, { plugins } from 'pretty-format'; // eslint-disable-line import/no-extraneous-dependencies
4+
import shallow from './shallow';
5+
6+
/**
7+
* Log pretty-printed shallow test component instance
8+
*/
9+
export default function debug(
10+
instance: ReactTestInstance | React.Element<*>,
11+
message?: any
12+
) {
13+
const { output } = shallow(instance);
14+
// eslint-disable-next-line no-console
15+
console.log(format(output), message || '');
16+
}
17+
18+
const format = input =>
19+
prettyFormat(input, {
20+
plugins: [plugins.ReactTestComponent, plugins.ReactElement],
21+
});

src/flushMicrotasksQueue.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// @flow
2+
/**
3+
* Wait for microtasks queue to flush
4+
*/
5+
export default function flushMicrotasksQueue(): Promise<any> {
6+
return new Promise(resolve => setImmediate(resolve));
7+
}

src/helpers/errorWithStack.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// @flow
2+
export default class ErrorWithStack extends Error {
3+
constructor(message: ?string, callsite: Function) {
4+
super(message);
5+
if (Error.captureStackTrace) {
6+
Error.captureStackTrace(this, callsite);
7+
}
8+
}
9+
}

src/helpers/getBy.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// @flow
2+
import * as React from 'react';
3+
import ErrorWithStack from './errorWithStack';
4+
5+
const getNodeByName = (node, name) =>
6+
node.type.name === name ||
7+
node.type.displayName === name ||
8+
node.type === name;
9+
10+
const getNodeByText = (node, text) =>
11+
(getNodeByName(node, 'Text') || getNodeByName(node, 'TextInput')) &&
12+
(typeof text === 'string'
13+
? text === node.props.children
14+
: text.test(node.props.children));
15+
16+
export const getByName = (instance: ReactTestInstance) => (
17+
name: string | React.Element<*>
18+
) => {
19+
try {
20+
return instance.find(node => getNodeByName(node, name));
21+
} catch (error) {
22+
throw new ErrorWithStack(`Error: Component not found.`, getByName);
23+
}
24+
};
25+
26+
export const getByText = (instance: ReactTestInstance) => (
27+
text: string | RegExp
28+
) => {
29+
try {
30+
return instance.find(node => getNodeByText(node, text));
31+
} catch (error) {
32+
throw new ErrorWithStack(`Error: Component not found.`, getByText);
33+
}
34+
};
35+
36+
export const getByProps = (instance: ReactTestInstance) => (props: {
37+
[propName: string]: any,
38+
}) => {
39+
try {
40+
return instance.findByProps(props);
41+
} catch (error) {
42+
throw new ErrorWithStack(`Error: Component not found.`, getByProps);
43+
}
44+
};
45+
46+
export const getByTestId = (instance: ReactTestInstance) => (testID: string) =>
47+
getByProps(instance)({ testID });
48+
49+
export const getAllByName = (instance: ReactTestInstance) => (
50+
name: string | React.Element<*>
51+
) => {
52+
const results = instance.findAll(node => getNodeByName(node, name));
53+
if (results.length === 0) {
54+
throw new ErrorWithStack(`Error: Components not found.`, getAllByName);
55+
}
56+
return results;
57+
};
58+
59+
export const getAllByText = (instance: ReactTestInstance) => (
60+
text: string | RegExp
61+
) => {
62+
const results = instance.findAll(node => getNodeByText(node, text));
63+
if (results.length === 0) {
64+
throw new ErrorWithStack(`Error: Components not found.`, getAllByText);
65+
}
66+
return results;
67+
};
68+
69+
export const getAllByProps = (instance: ReactTestInstance) => (props: {
70+
[propName: string]: any,
71+
}) => {
72+
const results = instance.findAllByProps(props);
73+
if (results.length === 0) {
74+
throw new ErrorWithStack(`Error: Components not found.`, getAllByProps);
75+
}
76+
return results;
77+
};

src/index.js

Lines changed: 9 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +1,10 @@
11
// @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-
import fireEvent from './fireEvent';
8-
9-
const getNodeByName = (node, name) =>
10-
node.type.name === name ||
11-
node.type.displayName === name ||
12-
node.type === name;
13-
14-
const getNodeByText = (node, text) =>
15-
(getNodeByName(node, 'Text') || getNodeByName(node, 'TextInput')) &&
16-
(typeof text === 'string'
17-
? text === node.props.children
18-
: text.test(node.props.children));
19-
20-
/**
21-
* Wait for microtasks queue to flush
22-
*/
23-
export const flushMicrotasksQueue = (): Promise<any> =>
24-
new Promise(resolve => setImmediate(resolve));
25-
26-
/**
27-
* Renders test component deeply using react-test-renderer and exposes helpers
28-
* to assert on the output.
29-
*/
30-
export const render = (
31-
component: React.Element<*>,
32-
options?: { createNodeMock: (element: React.Element<*>) => any }
33-
) => {
34-
const renderer = TestRenderer.create(component, options);
35-
const instance = renderer.root;
36-
37-
const getByName = (name: string | React.Element<*>) => {
38-
try {
39-
return instance.find(node => getNodeByName(node, name));
40-
} catch (error) {
41-
throw new ErrorWithStack(`Error: Component not found.`, getByName);
42-
}
43-
};
44-
45-
const getByText = (text: string | RegExp) => {
46-
try {
47-
return instance.find(node => getNodeByText(node, text));
48-
} catch (error) {
49-
throw new ErrorWithStack(`Error: Component not found.`, getByText);
50-
}
51-
};
52-
53-
const getByProps = (props: { [propName: string]: any }) => {
54-
try {
55-
return instance.findByProps(props);
56-
} catch (error) {
57-
throw new ErrorWithStack(`Error: Component not found.`, getByProps);
58-
}
59-
};
60-
61-
return {
62-
fireEvent,
63-
getByTestId: (testID: string) => instance.findByProps({ testID }),
64-
getByName,
65-
getAllByName: (name: string | React.Element<*>) =>
66-
instance.findAll(node => getNodeByName(node, name)),
67-
getByText,
68-
getAllByText: (text: string | RegExp) =>
69-
instance.findAll(node => getNodeByText(node, text)),
70-
getByProps,
71-
getAllByProps: (props: { [propName: string]: any }) =>
72-
instance.findAllByProps(props),
73-
update: renderer.update,
74-
unmount: renderer.unmount,
75-
};
76-
};
77-
78-
/**
79-
* Renders test component shallowly using react-test-renderer/shallow
80-
*/
81-
export const shallow = (instance: ReactTestInstance | React.Element<*>) => {
82-
const renderer = new ShallowRenderer();
83-
if (isValidElementType(instance)) {
84-
// $FlowFixMe - instance is React.Element<*> in this branch
85-
renderer.render(instance);
86-
} else {
87-
renderer.render(React.createElement(instance.type, instance.props));
88-
}
89-
const output = renderer.getRenderOutput();
90-
91-
return {
92-
output,
93-
};
94-
};
95-
96-
/**
97-
* Log pretty-printed shallow test component instance
98-
*/
99-
export const debug = (
100-
instance: ReactTestInstance | React.Element<*>,
101-
message?: any
102-
) => {
103-
const { output } = shallow(instance);
104-
// eslint-disable-next-line no-console
105-
console.log(format(output), message || '');
106-
};
107-
108-
const format = input =>
109-
prettyFormat(input, {
110-
plugins: [plugins.ReactTestComponent, plugins.ReactElement],
111-
});
112-
113-
class ErrorWithStack extends Error {
114-
constructor(message: ?string, callsite: Function) {
115-
super(message);
116-
if (Error.captureStackTrace) {
117-
Error.captureStackTrace(this, callsite);
118-
}
119-
}
120-
}
2+
import render from './render';
3+
import shallow from './shallow';
4+
import flushMicrotasksQueue from './flushMicrotasksQueue';
5+
import debug from './debug';
6+
7+
export { render };
8+
export { shallow };
9+
export { flushMicrotasksQueue };
10+
export { debug };

src/render.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// @flow
2+
import * as React from 'react';
3+
import TestRenderer from 'react-test-renderer'; // eslint-disable-line import/no-extraneous-dependencies
4+
import {
5+
getByTestId,
6+
getByName,
7+
getByText,
8+
getByProps,
9+
getAllByName,
10+
getAllByText,
11+
getAllByProps,
12+
} from './helpers/getBy';
13+
14+
/**
15+
* Renders test component deeply using react-test-renderer and exposes helpers
16+
* to assert on the output.
17+
*/
18+
export default function render(
19+
component: React.Element<*>,
20+
options?: { createNodeMock: (element: React.Element<*>) => any }
21+
) {
22+
const renderer = TestRenderer.create(component, options);
23+
const instance = renderer.root;
24+
25+
return {
26+
getByTestId: getByTestId(instance),
27+
getByName: getByName(instance),
28+
getByText: getByText(instance),
29+
getByProps: getByProps(instance),
30+
getAllByName: getAllByName(instance),
31+
getAllByText: getAllByText(instance),
32+
getAllByProps: getAllByProps(instance),
33+
update: renderer.update,
34+
unmount: renderer.unmount,
35+
};
36+
}

src/shallow.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// @flow
2+
import * as React from 'react';
3+
import { isValidElementType } from 'react-is';
4+
import ShallowRenderer from 'react-test-renderer/shallow'; // eslint-disable-line import/no-extraneous-dependencies
5+
6+
/**
7+
* Renders test component shallowly using react-test-renderer/shallow
8+
*/
9+
export default function shallow(
10+
instance: ReactTestInstance | React.Element<*>
11+
) {
12+
const renderer = new ShallowRenderer();
13+
if (isValidElementType(instance)) {
14+
// $FlowFixMe - instance is React.Element<*> in this branch
15+
renderer.render(instance);
16+
} else {
17+
renderer.render(React.createElement(instance.type, instance.props));
18+
}
19+
const output = renderer.getRenderOutput();
20+
21+
return {
22+
output,
23+
};
24+
}

0 commit comments

Comments
 (0)