Skip to content

Commit 05db7bc

Browse files
authored
feat: add debug.deep and debug.shallow (#37)
<!-- Please provide enough information so that others can review your pull request. --> <!-- Keep pull requests small and focused on a single change. --> ### Summary Adds API proposed by #33 (comment). Also component output is now highlighted: <img width="259" alt="screenshot 2018-10-16 at 19 33 25" src="https://user-images.githubusercontent.com/5106466/47035614-c10efb80-d17a-11e8-99ac-00f648880008.png"> ### Test plan Added tests for `debug`.
1 parent 03e2c4b commit 05db7bc

File tree

8 files changed

+190
-9
lines changed

8 files changed

+190
-9
lines changed

README.md

+44-4
Original file line numberDiff line numberDiff line change
@@ -273,12 +273,52 @@ Log prettified shallowly rendered component or test instance (just like snapshot
273273
import { debug } from 'react-native-testing-library';
274274

275275
debug(<Component />);
276-
// console.log:
277-
// <View>
278-
// <Text>Component</Text>
279-
// </View>
276+
debug.shallow(<Component />); // an alias for `debug`
280277
```
281278

279+
logs:
280+
281+
```jsx
282+
<TouchableOpacity
283+
activeOpacity={0.2}
284+
onPress={[Function bound fn]}
285+
>
286+
<TextComponent
287+
text="Press me"
288+
/>
289+
</TouchableOpacity>
290+
```
291+
292+
There's also `debug.deep` that renders deeply to stdout.
293+
294+
```jsx
295+
import { debug } from 'react-native-testing-library';
296+
297+
debug.deep(<Component />);
298+
```
299+
300+
logs:
301+
302+
```jsx
303+
<View
304+
accessible={true}
305+
isTVSelectable={true}
306+
onResponderGrant={[Function bound touchableHandleResponderGrant]}
307+
// ... more props
308+
style={
309+
Object {
310+
\\"opacity\\": 1,
311+
}
312+
}
313+
>
314+
<Text>
315+
Press me
316+
</Text>
317+
</View>
318+
```
319+
320+
Optionally you can provide a string message as a second argument to `debug`, which will be displayed right after the component.
321+
282322
## `flushMicrotasksQueue`
283323

284324
Wait for microtasks queue to flush. Useful if you want to wait for some promises with `async/await`.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"react": "16.6.0-alpha.8af6728",
2525
"react-native": "^0.57.3",
2626
"react-test-renderer": "16.6.0-alpha.8af6728",
27+
"strip-ansi": "^5.0.0",
2728
"typescript": "^3.1.1"
2829
},
2930
"peerDependencies": {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`debug 1`] = `
4+
"<TouchableOpacity
5+
activeOpacity={0.2}
6+
onPress={[Function bound fn]}
7+
>
8+
<TextComponent
9+
text=\\"Press me\\"
10+
/>
11+
</TouchableOpacity>"
12+
`;
13+
14+
exports[`debug.deep 1`] = `
15+
"<View
16+
accessible={true}
17+
isTVSelectable={true}
18+
onResponderGrant={[Function bound touchableHandleResponderGrant]}
19+
onResponderMove={[Function bound touchableHandleResponderMove]}
20+
onResponderRelease={[Function bound touchableHandleResponderRelease]}
21+
onResponderTerminate={[Function bound touchableHandleResponderTerminate]}
22+
onResponderTerminationRequest={[Function bound touchableHandleResponderTerminationRequest]}
23+
onStartShouldSetResponder={[Function bound touchableHandleStartShouldSetResponder]}
24+
style={
25+
Object {
26+
\\"opacity\\": 1,
27+
}
28+
}
29+
>
30+
<Text>
31+
Press me
32+
</Text>
33+
</View>"
34+
`;

src/__tests__/debug.test.js

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// @flow
2+
/* eslint-disable no-console */
3+
import React from 'react';
4+
import { TouchableOpacity, Text } from 'react-native';
5+
import stripAnsi from 'strip-ansi';
6+
import { debug } from '..';
7+
8+
function TextComponent({ text }) {
9+
return <Text>{text}</Text>;
10+
}
11+
12+
class Button extends React.Component<*> {
13+
render() {
14+
return (
15+
<TouchableOpacity onPress={this.props.onPress}>
16+
<TextComponent text={this.props.text} />
17+
</TouchableOpacity>
18+
);
19+
}
20+
}
21+
22+
test('debug', () => {
23+
// $FlowFixMe
24+
console.log = jest.fn();
25+
const component = <Button onPress={jest.fn} text="Press me" />;
26+
debug(component);
27+
28+
const output = console.log.mock.calls[0][0];
29+
30+
expect(stripAnsi(output)).not.toEqual(output);
31+
expect(stripAnsi(output)).toMatchSnapshot();
32+
33+
console.log.mockReset();
34+
35+
debug(component, 'test message');
36+
37+
expect(console.log).toBeCalledWith(output, 'test message');
38+
});
39+
40+
test('debug.shallow', () => {
41+
expect(debug.shallow).toBe(debug);
42+
});
43+
44+
test('debug.deep', () => {
45+
// $FlowFixMe
46+
console.log = jest.fn();
47+
const component = <Button onPress={jest.fn} text="Press me" />;
48+
debug.deep(component);
49+
50+
const output = console.log.mock.calls[0][0];
51+
52+
expect(stripAnsi(output)).not.toEqual(output);
53+
expect(stripAnsi(output)).toMatchSnapshot();
54+
55+
console.log.mockReset();
56+
57+
debug.deep(component, 'test message');
58+
59+
expect(console.log).toBeCalledWith(output, 'test message');
60+
});

src/debug.js

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,40 @@
11
// @flow
2+
/* eslint-disable no-console */
23
import * as React from 'react';
34
import prettyFormat, { plugins } from 'pretty-format'; // eslint-disable-line import/no-extraneous-dependencies
45
import shallow from './shallow';
6+
import render from './render';
57

68
/**
79
* Log pretty-printed shallow test component instance
810
*/
9-
export default function debug(
11+
function debugShallow(
1012
instance: ReactTestInstance | React.Element<*>,
1113
message?: any
1214
) {
1315
const { output } = shallow(instance);
14-
// eslint-disable-next-line no-console
16+
1517
console.log(format(output), message || '');
1618
}
1719

20+
/**
21+
* Log pretty-printed deep test component instance
22+
*/
23+
function debugDeep(instance: React.Element<*>, message?: any) {
24+
const { toJSON } = render(instance);
25+
26+
console.log(format(toJSON()), message || '');
27+
}
28+
1829
const format = input =>
1930
prettyFormat(input, {
2031
plugins: [plugins.ReactTestComponent, plugins.ReactElement],
32+
highlight: true,
2133
});
34+
35+
const debug = debugShallow;
36+
37+
debug.shallow = debugShallow;
38+
debug.deep = debugDeep;
39+
40+
export default debug;

typings/__tests__/index.test.tsx

+7
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,15 @@ const shallowTree: { output: React.ReactElement<any> } = shallow(
8181

8282
const waitForFlush: Promise<any> = flushMicrotasksQueue();
8383

84+
// debug API
8485
debug(<TestComponent />);
86+
debug(<TestComponent />, 'message');
8587
debug(getByNameString);
88+
debug(getByNameString, 'message');
89+
debug.shallow(<TestComponent />);
90+
debug.shallow(<TestComponent />, 'message');
91+
debug.deep(<TestComponent />);
92+
debug.deep(<TestComponent />, 'message');
8693

8794
const waitBy: Promise<ReactTestInstance> = waitForElement<ReactTestInstance>(
8895
() => tree.getByName('View')

typings/index.d.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,16 @@ export type WaitForElementFunction = <T = any>(
5151
interval?: number
5252
) => Promise<T>;
5353

54+
export type DebugFunction = (
55+
instance: ReactTestInstance | React.ReactElement<any>,
56+
message?: string
57+
) => void;
58+
59+
export type DebugAPI = DebugFunction & {
60+
shallow: DebugFunction;
61+
deep: (instance: React.ReactElement<any>, message?: string) => void;
62+
};
63+
5464
export declare const render: (
5565
component: React.ReactElement<any>,
5666
options?: RenderOptions
@@ -59,8 +69,6 @@ export declare const shallow: <P = {}>(
5969
instance: ReactTestInstance | React.ReactElement<P>
6070
) => { output: React.ReactElement<P> };
6171
export declare const flushMicrotasksQueue: () => Promise<any>;
62-
export declare const debug: (
63-
instance: ReactTestInstance | React.ReactElement<any>
64-
) => void;
72+
export declare const debug: DebugAPI;
6573
export declare const fireEvent: FireEventAPI;
6674
export declare const waitForElement: WaitForElementFunction;

yarn.lock

+12
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,11 @@ ansi-regex@^3.0.0:
842842
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
843843
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
844844

845+
ansi-regex@^4.0.0:
846+
version "4.0.0"
847+
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9"
848+
integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==
849+
845850
ansi-styles@^2.2.1:
846851
version "2.2.1"
847852
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
@@ -6275,6 +6280,13 @@ strip-ansi@^4.0.0:
62756280
dependencies:
62766281
ansi-regex "^3.0.0"
62776282

6283+
strip-ansi@^5.0.0:
6284+
version "5.0.0"
6285+
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f"
6286+
integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==
6287+
dependencies:
6288+
ansi-regex "^4.0.0"
6289+
62786290
strip-bom@3.0.0, strip-bom@^3.0.0:
62796291
version "3.0.0"
62806292
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"

0 commit comments

Comments
 (0)