mirror of
https://github.com/callstack/react-native-testing-library.git
synced 2026-09-18 23:09:04 +08:00
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 https://github.com/callstack/react-native-testing-library/pull/33#issuecomment-430302079. 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`.
This commit is contained in:
committed by
GitHub
parent
03e2c4b0f2
commit
05db7bcaac
@@ -273,12 +273,52 @@ Log prettified shallowly rendered component or test instance (just like snapshot
|
||||
import { debug } from 'react-native-testing-library';
|
||||
|
||||
debug(<Component />);
|
||||
// console.log:
|
||||
// <View>
|
||||
// <Text>Component</Text>
|
||||
// </View>
|
||||
debug.shallow(<Component />); // an alias for `debug`
|
||||
```
|
||||
|
||||
logs:
|
||||
|
||||
```jsx
|
||||
<TouchableOpacity
|
||||
activeOpacity={0.2}
|
||||
onPress={[Function bound fn]}
|
||||
>
|
||||
<TextComponent
|
||||
text="Press me"
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
```
|
||||
|
||||
There's also `debug.deep` that renders deeply to stdout.
|
||||
|
||||
```jsx
|
||||
import { debug } from 'react-native-testing-library';
|
||||
|
||||
debug.deep(<Component />);
|
||||
```
|
||||
|
||||
logs:
|
||||
|
||||
```jsx
|
||||
<View
|
||||
accessible={true}
|
||||
isTVSelectable={true}
|
||||
onResponderGrant={[Function bound touchableHandleResponderGrant]}
|
||||
// ... more props
|
||||
style={
|
||||
Object {
|
||||
\\"opacity\\": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text>
|
||||
Press me
|
||||
</Text>
|
||||
</View>
|
||||
```
|
||||
|
||||
Optionally you can provide a string message as a second argument to `debug`, which will be displayed right after the component.
|
||||
|
||||
## `flushMicrotasksQueue`
|
||||
|
||||
Wait for microtasks queue to flush. Useful if you want to wait for some promises with `async/await`.
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"react": "16.6.0-alpha.8af6728",
|
||||
"react-native": "^0.57.3",
|
||||
"react-test-renderer": "16.6.0-alpha.8af6728",
|
||||
"strip-ansi": "^5.0.0",
|
||||
"typescript": "^3.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`debug 1`] = `
|
||||
"<TouchableOpacity
|
||||
activeOpacity={0.2}
|
||||
onPress={[Function bound fn]}
|
||||
>
|
||||
<TextComponent
|
||||
text=\\"Press me\\"
|
||||
/>
|
||||
</TouchableOpacity>"
|
||||
`;
|
||||
|
||||
exports[`debug.deep 1`] = `
|
||||
"<View
|
||||
accessible={true}
|
||||
isTVSelectable={true}
|
||||
onResponderGrant={[Function bound touchableHandleResponderGrant]}
|
||||
onResponderMove={[Function bound touchableHandleResponderMove]}
|
||||
onResponderRelease={[Function bound touchableHandleResponderRelease]}
|
||||
onResponderTerminate={[Function bound touchableHandleResponderTerminate]}
|
||||
onResponderTerminationRequest={[Function bound touchableHandleResponderTerminationRequest]}
|
||||
onStartShouldSetResponder={[Function bound touchableHandleStartShouldSetResponder]}
|
||||
style={
|
||||
Object {
|
||||
\\"opacity\\": 1,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text>
|
||||
Press me
|
||||
</Text>
|
||||
</View>"
|
||||
`;
|
||||
@@ -0,0 +1,60 @@
|
||||
// @flow
|
||||
/* eslint-disable no-console */
|
||||
import React from 'react';
|
||||
import { TouchableOpacity, Text } from 'react-native';
|
||||
import stripAnsi from 'strip-ansi';
|
||||
import { debug } from '..';
|
||||
|
||||
function TextComponent({ text }) {
|
||||
return <Text>{text}</Text>;
|
||||
}
|
||||
|
||||
class Button extends React.Component<*> {
|
||||
render() {
|
||||
return (
|
||||
<TouchableOpacity onPress={this.props.onPress}>
|
||||
<TextComponent text={this.props.text} />
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
test('debug', () => {
|
||||
// $FlowFixMe
|
||||
console.log = jest.fn();
|
||||
const component = <Button onPress={jest.fn} text="Press me" />;
|
||||
debug(component);
|
||||
|
||||
const output = console.log.mock.calls[0][0];
|
||||
|
||||
expect(stripAnsi(output)).not.toEqual(output);
|
||||
expect(stripAnsi(output)).toMatchSnapshot();
|
||||
|
||||
console.log.mockReset();
|
||||
|
||||
debug(component, 'test message');
|
||||
|
||||
expect(console.log).toBeCalledWith(output, 'test message');
|
||||
});
|
||||
|
||||
test('debug.shallow', () => {
|
||||
expect(debug.shallow).toBe(debug);
|
||||
});
|
||||
|
||||
test('debug.deep', () => {
|
||||
// $FlowFixMe
|
||||
console.log = jest.fn();
|
||||
const component = <Button onPress={jest.fn} text="Press me" />;
|
||||
debug.deep(component);
|
||||
|
||||
const output = console.log.mock.calls[0][0];
|
||||
|
||||
expect(stripAnsi(output)).not.toEqual(output);
|
||||
expect(stripAnsi(output)).toMatchSnapshot();
|
||||
|
||||
console.log.mockReset();
|
||||
|
||||
debug.deep(component, 'test message');
|
||||
|
||||
expect(console.log).toBeCalledWith(output, 'test message');
|
||||
});
|
||||
+21
-2
@@ -1,21 +1,40 @@
|
||||
// @flow
|
||||
/* eslint-disable no-console */
|
||||
import * as React from 'react';
|
||||
import prettyFormat, { plugins } from 'pretty-format'; // eslint-disable-line import/no-extraneous-dependencies
|
||||
import shallow from './shallow';
|
||||
import render from './render';
|
||||
|
||||
/**
|
||||
* Log pretty-printed shallow test component instance
|
||||
*/
|
||||
export default function debug(
|
||||
function debugShallow(
|
||||
instance: ReactTestInstance | React.Element<*>,
|
||||
message?: any
|
||||
) {
|
||||
const { output } = shallow(instance);
|
||||
// eslint-disable-next-line no-console
|
||||
|
||||
console.log(format(output), message || '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Log pretty-printed deep test component instance
|
||||
*/
|
||||
function debugDeep(instance: React.Element<*>, message?: any) {
|
||||
const { toJSON } = render(instance);
|
||||
|
||||
console.log(format(toJSON()), message || '');
|
||||
}
|
||||
|
||||
const format = input =>
|
||||
prettyFormat(input, {
|
||||
plugins: [plugins.ReactTestComponent, plugins.ReactElement],
|
||||
highlight: true,
|
||||
});
|
||||
|
||||
const debug = debugShallow;
|
||||
|
||||
debug.shallow = debugShallow;
|
||||
debug.deep = debugDeep;
|
||||
|
||||
export default debug;
|
||||
|
||||
@@ -81,8 +81,15 @@ const shallowTree: { output: React.ReactElement<any> } = shallow(
|
||||
|
||||
const waitForFlush: Promise<any> = flushMicrotasksQueue();
|
||||
|
||||
// debug API
|
||||
debug(<TestComponent />);
|
||||
debug(<TestComponent />, 'message');
|
||||
debug(getByNameString);
|
||||
debug(getByNameString, 'message');
|
||||
debug.shallow(<TestComponent />);
|
||||
debug.shallow(<TestComponent />, 'message');
|
||||
debug.deep(<TestComponent />);
|
||||
debug.deep(<TestComponent />, 'message');
|
||||
|
||||
const waitBy: Promise<ReactTestInstance> = waitForElement<ReactTestInstance>(
|
||||
() => tree.getByName('View')
|
||||
|
||||
Vendored
+11
-3
@@ -51,6 +51,16 @@ export type WaitForElementFunction = <T = any>(
|
||||
interval?: number
|
||||
) => Promise<T>;
|
||||
|
||||
export type DebugFunction = (
|
||||
instance: ReactTestInstance | React.ReactElement<any>,
|
||||
message?: string
|
||||
) => void;
|
||||
|
||||
export type DebugAPI = DebugFunction & {
|
||||
shallow: DebugFunction;
|
||||
deep: (instance: React.ReactElement<any>, message?: string) => void;
|
||||
};
|
||||
|
||||
export declare const render: (
|
||||
component: React.ReactElement<any>,
|
||||
options?: RenderOptions
|
||||
@@ -59,8 +69,6 @@ export declare const shallow: <P = {}>(
|
||||
instance: ReactTestInstance | React.ReactElement<P>
|
||||
) => { output: React.ReactElement<P> };
|
||||
export declare const flushMicrotasksQueue: () => Promise<any>;
|
||||
export declare const debug: (
|
||||
instance: ReactTestInstance | React.ReactElement<any>
|
||||
) => void;
|
||||
export declare const debug: DebugAPI;
|
||||
export declare const fireEvent: FireEventAPI;
|
||||
export declare const waitForElement: WaitForElementFunction;
|
||||
|
||||
@@ -842,6 +842,11 @@ ansi-regex@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
|
||||
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
|
||||
|
||||
ansi-regex@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9"
|
||||
integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==
|
||||
|
||||
ansi-styles@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
|
||||
@@ -6275,6 +6280,13 @@ strip-ansi@^4.0.0:
|
||||
dependencies:
|
||||
ansi-regex "^3.0.0"
|
||||
|
||||
strip-ansi@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f"
|
||||
integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==
|
||||
dependencies:
|
||||
ansi-regex "^4.0.0"
|
||||
|
||||
strip-bom@3.0.0, strip-bom@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
|
||||
|
||||
Reference in New Issue
Block a user